Libcurl很少在内容POST上崩溃

Libcurl infrequently crashes on content POST

本文关键字:POST 崩溃 Libcurl      更新时间:2023-10-16

我正在使用libCURL库向外部设备发送HTTP POST命令。我有两个基本的命令。第一个告诉设备擦除设备上的当前内容,第二个发送新内容。我对两者使用相同的POST标头结构/地址,唯一的区别是在"发送内容"命令期间附加数据。两个命令都能正确执行:第一个擦除数据,第二个发送。然而,在"发送内容"命令之后,程序很少(约30%的时间)崩溃。没有给出错误。正如我之前所说,在数据发送之前,它不会崩溃,也不会一直发生,这让它特别令人恼火。

代码附在下面。在发送程序需要一致退出"curl_easy_perform(curl)"操作的内容后,我是否缺少了什么?我对这类事情还相当缺乏经验,愿意接受你的任何建议。

int fnSendContent(BMP* pbmpContent)
{
    using namespace std;
    int Error = 0;
    CURL* curl;
    CURLcode res;
    struct curl_slist *headerlist=NULL;
    static const char buf[] = "aaaaaaaaa";
    CString str;
    string sURL;
    long lTimeout = 10;
    //Pass image into char array so that it can be sent to VIP
    ifstream fsContent;
    fsContent.open("MyImage.bmp",ios_base::binary);
    fsContent.seekg(0,ios::end);
    long lBMP_size = fsContent.tellg();
    fsContent.seekg(0,ios::beg);
    char* pcContent = new char[lBMP_size];
    for (int i = 0; i < lBMP_size; i++)
        pcContent[i] = 'F';
    bool bit = fsContent.eof();
    fsContent.read(pcContent,lBMP_size);
    fsContent.close();
    string Content_Length = "Content-Length: " + to_string((long long)lBMP_size);
    curl_global_init(CURL_GLOBAL_ALL);
    curl = curl_easy_init();
    //Build header
    headerlist = curl_slist_append(headerlist, buf);
    headerlist = curl_slist_append(headerlist, "Authorization: MyAuth);
    headerlist = curl_slist_append(headerlist, "Accept: MyAccept");
    headerlist = curl_slist_append(headerlist, "Content-Type: image/bmp");
    headerlist = curl_slist_append(headerlist, "Connection: keep-alive");
    headerlist = curl_slist_append(headerlist, Content_Length.c_str());
    headerlist = curl_slist_append(headerlist, "Expect: "); //Supress "Expect:" heading
    //Set URL to receive POST
    curl_easy_setopt(curl, CURLOPT_VERBOSE, true);
    curl_easy_setopt(curl,CURLOPT_POST, true);
    curl_easy_setopt(curl, CURLOPT_HEADER, true);
    curl_easy_setopt(curl,CURLOPT_TIMEOUT, lTimeout);
    curl_easy_setopt(curl, CURLOPT_URL, "http://URL:Port/Command");
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, lBMP_size);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, pcContent);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
    //Send
    res = curl_easy_perform(curl); //Crash occurs on send
    CString str2(curl_easy_strerror(res));//Get Error Explanation
    if(res != CURLE_OK)
    {
        str2.Format(_T("curl_easy_perform() failed: %s [%d]"), str2,res);
        DebugOut->AddString(str2);
        Error = E_SHOW_IMG;
    }
    curl_easy_cleanup(curl);
    curl_global_cleanup();
    curl_slist_free_all(headerlist);
    delete[] pcContent;
    return Error;
}

编辑:Daniel要求更多信息:

崩溃发生在我通过"curl_easy_perform(curl)"发送标头和数据之后,但在它成功返回到程序的其余部分之前。我在VC++中编码,只收到一般的"发生错误"。错误发生在收到数据之后,这让我觉得我没有正确地终止命令。下面给出了一个崩溃的POST命令的WireShark打印输出。

    Source     Destination  Protocol  Length       Info
  ------------------------------------------------------------
  |MySourceIP  | MyDestIP |   HTTP  | 16438  |  POST /Command|
  ------------------------------------------------------------
POST /Command HTTP/1.1..Host: URL:Port..Authorization: My Auth..Content-Type:
image/bmp..Accept: MyAccept..Connection: keep-alive..Content-Length: 61
494....BM6.......6...(..........
[Followed by 61,494 bytes of data ending in null]

CURLOPT_POSTFIELDSIZE_LARGE选项接受一个"curl_off_t"参数,但您传入了一个"long"。