libcurl遇到的问题总结
1、返回411
HTTP 411 错误表示客户端发送的请求没有包含必需的 Content-Length 头字段;
解决方案一 手动指定Content-Length pCurlHeadList = curl_slist_append(pCurlHeadList, “Content-length: 0”);
解决方案二 curl_easy_setopt(pCurlHandle, CURLOPT_POSTFIELDS, “”);
在这里我采用第二种,将头和数据进行分离
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd"><HTML><HEAD><TITLE>Length Required</TITLE><META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD><BODY><h2>Length Required</h2><hr><p>HTTP Error 411. The request must be chunked or have a content length.</p></BODY></HTML>
//常规调用
string CMESDLL::postMessageToUrl(string p_strUrlHead , string p_strData)
{if (p_strUrlHead.size() < 5){return "false , IP地址设置错误";}CURL *curl;CURLcode res;curl = curl_easy_init();if(curl) {curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &CurlWriteCallback);curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");curl_easy_setopt(curl, CURLOPT_URL, p_strUrlHead.c_str());curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");struct curl_slist *headers = NULL;curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);/*curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "{\"EqNo\":\"tyuhihytftf\" , \"CapacityQuantity\":\"0\" , \"EqProcess\":\"55555555555555\" ,\\"PanelNo\":\"333\" , \"OrderNo\":\"15555555555\" }");*///curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);curl_easy_setopt(curl, CURLOPT_POSTFIELDS,p_strData.c_str());res = curl_easy_perform(curl);if(res == CURLE_OPERATION_TIMEDOUT){m_str_ret = "连接超时";}if(res !=CURLE_OK ){m_str_ret = "false , 请求返回数据异常 , 和服务器通信异常";}else{m_str_ret = g_str_ret;}}curl_easy_cleanup(curl);return g_str_ret;
}
2、返回值 说格式不对
curl_easy_setopt(curl, CURLOPT_URL, p_strUrlHead.c_str());
第二个参数一定要转换一下,从string 转成char*
3、数据传输过程中存在中文乱码,再回调函数里进行处理,如下
std::string wstring2string(std::wstring wstr)
{std::string result;//获取缓冲区大小,并申请空间,缓冲区大小事按字节计算的 int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL);char* buffer = new char[len + 1];//宽字节编码转换成多字节编码 WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), buffer, len, NULL, NULL);buffer[len] = '\0';//删除缓冲区并返回值 result.append(buffer);delete[] buffer;return result;
}void writeLog(string p_str)
{FILE*fp = fopen("D:\\log.txt" , "a+");if(fp==NULL){return;}fwrite(p_str.c_str() , 1,p_str.size(),fp);fclose(fp);
}
std::wstring utf8string2wstring(const std::string& str)
{static std::wstring_convert< std::codecvt_utf8<wchar_t> > strCnv;return strCnv.from_bytes(str);
}
std::string urlEncode(const std::string& value) {std::ostringstream escaped;escaped.fill('0');escaped << std::hex;for(int i=0;i<value.size();++i){char c = value[i];if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~'|| c=='{' || c=='}') {escaped << c;continue;}// 使用百分号编码非字母数字字符escaped << '%' << std::setw(2) << int((unsigned char)c);}return escaped.str();
}size_t CurlWriteCallback(char* buf, size_t size, size_t nmemb, void* up)
{buf[nmemb] = '\0';g_str_ret = buf;wstring ss = utf8string2wstring(g_str_ret);g_str_ret = wstring2string(ss);writeLog(g_str_ret);writeLog("\r\n");return size * nmemb;
}
头文件如下
头文件如下:
#include <codecvt>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>
