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);
}
// ...
}
我正在做一个小项目,我想使用 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);
}
// ...
}