Libcurl 多次重试机制跳过请求数据

Libcurl multi retry mechanism skips over requesting data

我正在做一个小项目,我想使用 libcurl multi 一次请求多条数据。这是一个例子

CURL* array[] = {
    curl_easy_init(),
    curl_easy_init(),
    curl_easy_init()
};
CURLM* multi = curl_multi_init();

curl_easy_setopt(array[0], CURLOPT_URL, "https://www.example.com/");
curl_easy_setopt(array[1], CURLOPT_URL, "https://www.example.com/");
curl_easy_setopt(array[2], CURLOPT_URL, "https://americas.api.riotgames.com/riot/account/v1/accounts/by-puuid/Dxon1TsoGLOAvUykGYErrEPAT_U9YkQ_jNFZpRxYpfRFwnaYVFULVshNQnZapa4qR_pe5sSBn5MQvw");
for (int i = 0; i < 3; i++) {
    curl_multi_add_handle(multi, array[i]);
}
int retry = 3;
loop:
int run = 1;
while (run) {
    CURLMcode mc = curl_multi_perform(multi, &run);
    if (mc == CURLM_OK) {
        mc = curl_multi_poll(multi, NULL, 0, 0, NULL);
    }
    if (mc != CURLM_OK) { // no else because catch both error possibilities
        exit(0); // error in curl multi
    }
}
CURLMsg *msg;
long rerun = 0;
int msgNum = 0;
while (msg = curl_multi_info_read(multi, &msgNum)) {
    if (msg->msg == CURLMSG_DONE) {
        if (msg->data.result != CURLE_OK) {
            puts("ERROR");
            exit(0); // error with transfer
        }
        long httpCode;
        curl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, &httpCode);
        if (httpCode == 200) {
            curl_multi_remove_handle(multi, msg->easy_handle);
        } else { // error with serverside
            rerun = httpCode;
            printf("\nError : %d\n", rerun);
        }
    } else {
        puts("ERROR");
        exit(0); // return num not compelted?
    }
}
puts("NExt");
if (rerun && --retry) {
    printf("%d - %d\n", retry, rerun);
    Sleep(1000);
    goto loop;
}
puts("Finisheed");

exit(0);

所以首先我制作了一个 curl easy handles 数组,填写所有信息,并将它们放入 curl_multi 以执行请求。如果我将所有 URL 设置为“https://www.example.com/”,代码工作正常。

但就我而言,我从一个可能根本无法工作的站点(数组 [2] 中的 URL)请求,因此我采用了重试机制。如果有一个不是 200 的 httpCode,那么我重做请求,但只重做那些失败的请求(我删除了所有成功完成的简单句柄)。

然而,重试机制似乎只重试一次(当它应该重试 3 次时)并且似乎跳过了其余部分。这是我得到的输出

...stuff from example.com...
Error : 401
NExt
2 - 401
NExt
Finisheed

如您所见,它只重试一次然后就停止了,但显然有一个错误,因为它没有打印出正确的响应。

谁能指出我正确的方向?

curl easy 如果保存在 curl multi 中,则不会重新运行。删除并重新添加。否则你会在第二次迭代中得到 !run!msg

if (msg->msg == CURLMSG_DONE) {
    // ...
    curl_multi_remove_handle(multi, msg->easy_handle);
    long httpCode;
    curl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, &httpCode);
    if (httpCode != 200) {
        rerun = httpCode;
        printf("\nError : %d\n", rerun);
        curl_multi_add_handle(multi, msg->easy_handle);
    }
    // ...
}