在超时时处理 libcurl 流产

Handling libcurl abortion on timeout

我正在使用 libcurl 编写一个带有 http 客户端的 C 守护进程。 我希望它对错误具有弹性,因为守护进程将生活在一个危险的环境中。

我添加了超时控制,不会无休止地等待。

curl_easy_setopt(ezhandle, CURLOPT_TIMEOUT, 300); //timeout after 5 minutes (use sigalarm)
curl_easy_setopt(ezhandle, CURLOPT_CONNECTTIMEOUT, 2); //timeout after 2 seconds (use sigalarm)
curl_easy_setopt(ezhandle, CURLOPT_NOSIGNAL, 1); // Do not use signal

但是当请求超时(或其他类型的错误)时,库会发送一个中止信号。 我的守护进程被杀死了...... 我收到错误:

libcurl: (28) Connection timed out after 2000 milliseconds
Aborted

我尝试处理信号(使用 signal(6,mycallback)),但根据 How to Handle SIGABRT signal? 这是不可能的。

根据文档:https://curl.se/libcurl/c/CURLOPT_TIMEOUT.html and https://curl.se/libcurl/c/CURLOPT_CONNECTTIMEOUT.html 它可能会导致信号警报。 我尝试用 signal(13,myhandler) 捕获 sigalarm 但它没有被触发。

解决方案是什么?

PS: 我相信线程可能是一个解决方案,但我从未使用过它们,我想避免麻烦。

此代码导致错误:

printf("%04X %04X %04X\n",LIBCURL_VERSION_MAJOR, LIBCURL_VERSION_MINOR, 
LIBCURL_VERSION_PATCH );
res = curl_easy_perform(ezhandle);
if(catchError(res,ezhandle,errbuf)==-1){
  printf("error \n");
  fclose(downloaded_file);
  //return -1;  // THIS IS THE ONLY CHANGE
};

if(CURLE_OK == res){}
if(ezhandle) {
  printf("ezhandle cleanup\n");
  curl_easy_cleanup(ezhandle);
}
printf("Does it execute this instruction ?"); // It stops before
return 0;
}

结果如下:

http://192.168.174.61/token
0007 0028 0000
libcurl: (28) Operation timed out after 10000 milliseconds with 0 bytes 
received
error
ezhandle cleanup
Aborted

这更正了问题:

if(catchError(res,ezhandle,errbuf)==-1){
printf("error \n");
fclose(downloaded_file);
return -1;  // THIS IS THE ONLY CHANGE
};

您代码中的注释暗示 cURL 会执行 SIGALRM(值 13)信号,这不是您稍后讨论的 SIGABRT (6)。

你试过了吗signal(SIGALRM, callback)

我发现了我的错误,

在我的函数“catchError”中,我已经清理了 ezhandle。连续两次清洗 ezhandle 惹人流产