C++ LibCurl错误重试

7
我希望在我的C++程序中重试curl连接5次。当连续失败5次时,应该停止程序的执行。然而,在这一点上它只会在第一个错误后停止。我能够捕获错误,但是我不知道如何执行以前的curl连接。例如,使用jQuery,我可以使用类似$.ajax(this);的东西。对于C++中的LibCurl,我正在寻找类似的解决方案。
我的当前LibCurl代码如下所示,请注意我使用多个curl连接,它们都有其他设置,因此我希望有一个通用的方法,可以在我的LibcurlError函数中用于所有LibCurl错误。
curl = curl_easy_init();
if (curl) {
    CurlResponse = "";
    host = "http://google.com";
    LibcurlHeaders = curl_slist_append(NULL, "Expect:");
    if (ProxyAddress.length() > 0) {
        curl_easy_setopt(curl, CURLOPT_PROXY, ProxyAddress.c_str());
        }
    curl_easy_setopt(curl, CURLOPT_URL, (host).c_str());
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER , 1);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST , 1);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, LibcurlHeaders);
    res = curl_easy_perform(curl);
    curl_slist_free_all(LibcurlHeaders);
    if (res != CURLE_OK) {


        //AT THIS POINT I WOULD LIKE TO RETRY FOR 5 TIMES WHICH I WOULD LIKE TO CATCH IN MY LibcurlError FUNCTION.


        LibcurlError(curl_easy_strerror(res), host);
        }
    curl_easy_cleanup(curl);
    }
curl_global_cleanup();


void LibcurlError(string error, string host) {
    //IF FAILED FOR LESS THEN 5 TIMES IN A ROW -> RETRY CURL
    //ELSE I WOULD LIKE TO EXECUTE MY ORIGINAL CODE WHICH IS STATED BELOW 

    Message = "LibCurl Error: ";
    if (error == "Couldn't resolve host name") {
        Message.append("Couldn't connect to the server of ");
        if (host.find("google.com") != string::npos) {
            Message.append("Google");
            }
        else {
            Message.append("'" + host + "'");
            }
        }
    else {
        Message.append("'" + error + "'");
        }
    cout << Message << endl;
    system("pause");
    exit(0);
    }

3
只需在循环中多次调用 curl_easy_perform,您可以根据需要调用多少次。具体问题是什么? - Igor Tandetnik
1
在捕获错误之前不要清除头文件。当然,您必须保持LibcurlHeaders的活性,只要您打算使用它。 - Igor Tandetnik
1
Igor:我认为你应该把那个变成一个答案... - Daniel Stenberg
1
应该将setopts和curl_easy_cleanup放在循环内(例如,在每次迭代中完成)还是可以在成功调用一次后仅进行一次初始化和清理? - Richard Sand
1
@RichardSand,循环外一次就足够了。 - TVA van Hesteren
显示剩余4条评论
1个回答

0

没有特定的CURL方法可以完成这个任务,因为可以通过重复调用curl_easy_perform来实现。

以下是如何使用循环重试CURL请求的代码(至少是相关部分):

#include <unistd.h>
#include <curl/curl.h>

/*
 * This is the maximum number of times CURL will run
 */
const int max_attempts = 5;

curl = curl_easy_init();
if (curl) {
    CurlResponse = "";
    host = "http://google.com";
    LibcurlHeaders = curl_slist_append(NULL, "Expect:");
    if (ProxyAddress.length() > 0) {
        curl_easy_setopt(curl, CURLOPT_PROXY, ProxyAddress.c_str());
        }
    curl_easy_setopt(curl, CURLOPT_URL, (host).c_str());
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER , 1);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST , 1);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, LibcurlHeaders);
    for (int i = 1; i <= max_attempts &&
        (res = curl_easy_perform(curl)) != CURLE_OK; i++) {
         /*
          * At this point, you would sleep
          * for some seconds between requests
          */
          const int sleep_secs = 1;
          sleep(sleep_secs);
     }
    // As others have mentioned, you should delete this line:
    //curl_slist_free_all(LibcurlHeaders);

    if (res != CURLE_OK) {
        // The max retries have all failed
        LibcurlError(curl_easy_strerror(res), host);
    }
    else {
        // The request has succeeded in the first `max_retries` attempts
        // ...
    }
    curl_easy_cleanup(curl);
}
curl_global_cleanup();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接