1

わかりましたので、私の問題は基本的にこれです。cURL を使用して ~5 秒ごとに HTTPS URL から JSON をダウンロードするプログラムをコーディングしました。私はそれを一晩実行したままにし、約 2 時間完全に実行した後、URL へのすべての接続に失敗しました。少なくとも目が覚めてチェックしたときはインターネットを実行していましたが、プログラムは失敗し続けました。プログラムを再起動するとすぐに、再び機能し始めました。イーサネット コードを 1 分間引っ張ってから再度接続することで問題を再現しようとしましたが、接続が再確立された後、プログラムは完全に機能しました。ヘルプ?:D

コンテキスト: cURL 7.24.0 にリンクされた Xcode 4.6.2 での開発、コンパイル、および実行。

私が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 Web サイトから:

この関数は最初に呼び出す関数である必要があり、他の easy-function への入力として使用する必要がある CURL easy ハンドルを返します。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 に答える