【问题】C++ libcurl实现PUT时阻塞问题
解决方案
将
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
换成
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
原因
在项目中对方要求使用PUT来发送控制指令,于是直接使用Libcurl来实现。原本是一个非常简单的事情,确怎么都没发送出控制指令,单步执行发现curl_easy_perform
阻塞了,网上查了各种原因,发现都不适用,最后对比Postman发送数据,发现上述问题。最终实现代码如下:
size_t write_callback(void* contents, size_t size, size_t nmemb, void* userp) {
// 处理响应数据
char* pData = (char*)contents;
cout << "contents == " << pData << endl;
return size * nmemb; // 返回接收到的字节数,以便libcurl知道数据已经被接收
}
static bool initPutUpPlat(const char* url, string strUser, string strPsd, string& strRes)
{
string strke = strUser + ":" + strPsd;
curl_global_init(CURL_GLOBAL_ALL);
CURLcode code;
CURL* conn;
conn = curl_easy_init();
if (NULL == conn)
{
std::cout << stderr << " Failed to create CURL connection" << std::endl;
exit(EXIT_FAILURE);
}
code = curl_easy_setopt(conn, CURLOPT_URL, url);
if (code != CURLE_OK)
{
std::cout << stderr << " Failed to set error buffer " << code << std::endl;
return false;
}
code = curl_easy_setopt(conn, CURLOPT_USERPWD, strke.c_str());
if (code != CURLE_OK)
{
std::cout << stderr << " Failed to set error buffer " << code << std::endl;
return false;
}
code = curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
if (code != CURLE_OK)
{
std::cout << stderr << " Failed to set error buffer " << code << std::endl;
return false;
}
code = curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PUT");
if (code != CURLE_OK)
{
std::cout << stderr << " Failed to set error buffer " << code << std::endl;
return false;
}
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "Content-Type: text/plain");
code = curl_easy_setopt(conn, CURLOPT_HTTPHEADER, headers);
if (code != CURLE_OK)
{
std::cout << stderr << " Failed to set error buffer " << code << std::endl;
return false;
}
const char* data = "指令....";
code = curl_easy_setopt(conn, CURLOPT_POSTFIELDS, data);
if (code != CURLE_OK)
{
std::cout << stderr << " Failed to set error buffer " << code << std::endl;
return false;
}
code = curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, write_callback); // 设置回调函数以处理上传的数据
if (code != CURLE_OK)
{
std::cout << stderr << " Failed to set error buffer " << code << std::endl;
return false;
}
code = curl_easy_perform(conn);
if (code != CURLE_OK)
{
return false;
}
curl_slist_free_all(headers);//记得释放
return true;
}
为何阻塞
注意:如果使用CURLOPT_PUT
一定要记得添加传输大小CURLOPT_INFILESIZE_LARGE
通过put上传文件
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(curl, CURLOPT_PUT, 1L);
curl_easy_setopt(curl, CURLOPT_READDATA, fp); // FILE *fp = fopen("/path/filename");
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, fsize); // fsize = sizeof /path/filename