1

好的,所以我的问题基本上是这样的。我编写了一个程序,它使用 cURL 每约 5 秒从 HTTPS URL 下载 JSON。我让它在一夜之间运行,并且在完美运行了大约 2 小时后,与 URL 的每个连接都失败了。我有互联网运行,至少当我醒来并检查时,但程序一直失败。一旦我重新启动程序,它就会再次开始工作。我尝试通过拉动我的以太网代码一分钟然后将其重新连接来重现问题,但在重新建立连接后程序运行良好。帮助?:D

上下文:在 Xcode 4.6.2 中开发、编译和运行,链接到 cURL 7.24.0。

我有一个JSONDownloader由我定义的类,我打电话down.get("https://url.of.the/info");来获取信息。

这是 JSONDownloader 的代码:

std::string JSONDownloader::DownloadedResponse;
bool JSONDownloader::valid_;

int JSONDownloader::dataStore(char *data, size_t size, size_t nmemb, std::string *buffer_in) {
    if (buffer_in != NULL)
    {         
        DownloadedResponse.erase();
        DownloadedResponse.append(data, size * nmemb);

        return (int)(size * nmemb);
    } else throw "error in HTTPS get!";

    return 0;
}

std::string JSONDownloader::get(std::string URL) {
    CURL *curl;
    CURLcode res;
    struct curl_slist *headers=NULL; // init to NULL is important
    std::ostringstream oss;
    curl_slist_append(headers, "Accept: application/json");
    curl_slist_append( headers, "Content-Type: application/json");
    curl_slist_append( headers, "charsets: utf-8");
    curl = curl_easy_init();

    if (curl)
    {
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_URL, URL.c_str());
        curl_easy_setopt(curl, CURLOPT_HTTPGET,1);
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,dataStore);
        curl_easy_setopt(curl,CURLOPT_TIMEOUT,20);
        res = curl_easy_perform(curl);

        if (CURLE_OK == res)
        {
            valid_ = true;
            return DownloadedResponse;
        } else valid_ = false;
    }

    return "error in HTTP get!";
}

bool JSONDownloader::valid() {
    return valid_;
}

2 小时后,该函数仅"error in HTTP get!"针对每次调用返回,并且valid_标志始终设置为 false。现在,我将它重写为 return res,看看它是否给了我错误的原因,我会用信息更新你们。有什么见解吗?谢谢!

更新:它失败并出现错误 56,CURLE_RECV_ERROR,由文档描述为“接收网络数据失败”。

4

1 回答 1

3

完成后您没有清理连接。您需要调用curl_easy_cleanup()以完全关闭连接并释放已为其分配的资源。

来自 LibCURL 网站:

该函数必须是第一个调用的函数,它返回一个 CURL 简单句柄,您必须将其用作其他简单函数的输入。curl_easy_init 初始化 curl,并且此调用必须在操作完成时对 curl_easy_cleanup(3) 进行相应的调用。


以下是处理清理所需的更改

std::string JSONDownloader::get(std::string URL)
{
    CURL *curl;
    // .... snipped code
    curl = curl_easy_init();

    if (curl)
    {
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        // .... snipped code
        res = curl_easy_perform(curl);

        curl_easy_cleanup(curl);  // <---- clean up before we return!

        if (CURLE_OK == res)
        {
            valid_ = true;
            return DownloadedResponse;
        } else valid_ = false;

    }

    return "error in HTTP get!";
}
于 2013-05-25T21:00:49.907 回答