域函数(Qt)深受QByteArray的陷害
这段时间一直在学习域函数之类的问题,下午正好有机会和大家讨论一下.
这两天在护维前以写的一个服务端件软,这件软应用Qt发开的。
调试了2天,于终找到了案答。原因正是我太相信Qt的接口,QByteArray类供提了转换成char *的接口,可以这么转换:
QByteArray arr; arr.toLatin1().data();
中断一下,前以在应用arr.toAscii().data()的时候也碰到了严峻的问题。
【QString和char *的转换】
对于应用数量较少的数据,arr.toLatin1().data()可以直接作为参数传递,但对于全安性要求很严格的,就要虑考新重拷贝到自建的存内域区了(char *)。
【项目分析】:
Windows服务端,该件软模拟登岸某个网站,抓取隐藏域,自动识别验证码,生成表单域并经过url编码,post给网站,实现模拟登岸。
【调试】:
昨天开始调试,发明验证码识别准确的,模拟录登失败,这问题让我很解费。于终,在应用了curl调试能功后(CURLOPT_DEBUGFUNCTION, CURLOPT_VERBOSE),原形毕露了。结果竟然是http头的表单域不完整,如下:
Content-Type: application/x-www-form-urlencoded
前面没内容了。
有bug的码代:
bool CCurl::Post(const QString &actionUrl, const QString &fieldsInfo, QString &htmlStr) { //... curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, fieldsInfo.toLatin1().data()); //... return true; }
注意,这里先明说一下curl_easy_setopt函数,该函数置设了表单域,须要一个char *针指,但curl_easy_setopt函数并没有真正的拷贝char *数据,只是利用了该针指读取对应的数据(这里我经过测试)。所以才会涌现curl交提的时候,表单域不完整的bug。
行执功成的码代:
bool CCurl::Post(const QString &actionUrl, const QString &fieldsInfo, QString &htmlStr) { //拷贝 int len = fieldsInfo.size(); char *buf = new char[len+1]; qMemCopy(buf, fieldsInfo.toLatin1().data(), len); buf[len] = 0; buf[fieldsInfo.size()] = 0; //... curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, fieldsInfo.toLatin1().data()); //... delete [] buf;//释放 return true; }
自己请申内容空间存保这部分内容,当curl交提完成后,再释放存内,这样就能够证保curl交提表单域畸形了。
【总结】:
应用curl,若涌现问题,必须要应用CURLOPT_DEBUGFUNCTION和CURLOPT_VERBOSE两个选项。
文章结束给大家分享下程序员的一些笑话语录:
一程序员告老还乡,想安度晚年,于是决定在书法上有所造诣。省略数字……,准备好文房4宝,挥起毛笔在白纸上郑重的写下:Hello World