如何使libcurl c++调用超时和/或知道调用中何时发生超时

How to timeout a libcurl C++ call and/or know when a timeout has happened in the call

本文关键字:调用 超时 何时发 何使 libcurl c++      更新时间:2023-10-16

我正在尝试用我的c++程序下载远程html页面,但是有一些url超时发生,但我不知道如何处理这个,所以程序将无限期地挂起。

virtual void downloadpage(string pageaddress) {
    CURL *curl;
        CURLcode informationdownloaded;
        curl = curl_easy_init();
        if (curl) { 
            curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.A.B.C Safari/525.13");
            curl_easy_setopt(curl, CURLOPT_URL, pageaddress.c_str());
            curl_easy_setopt(curl, CURLOPT_HEADER, 0);
            curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writepageinformation);
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, &pageinformation);
            informationdownloaded = curl_easy_perform(curl);
            curl_easy_cleanup(curl);
    }
}

下面是我的函数,通过"writepageinformation"函数将一个页面的html源代码下载到一个名为"pageinformation"的字符串变量中。

informationdownloaded = curl_easy_perform(curl);

你也可以为下载指定超时时间

curl_easy_setopt(hCurl, CURLOPT_TIMEOUT, iTimeoutSeconds); // timeout for the URL to download

这是一个阻塞的调用,直到整个文件被下载。如果您有兴趣中断被阻塞的调用(用于杀死信号),请安装进度回调,如下所示

curl_easy_setopt(hCurl, CURLOPT_NOPROGRESS, 0);
curl_easy_setopt(hCurl, CURLOPT_PROGRESSFUNCTION, progress_callback);
curl_easy_setopt(hCurl, CURLOPT_PROGRESSDATA, this);
static int progress_callback(void *clientp,
                           double dltotal,
                           double dlnow,
                           double ultotal,
                           double ulnow)
{
    CLASS &obj = *(CLASS*)clientp;

    if (obj.exit)
      return 1; // if u want the signal curl to unblock and return from curl_easy_perform
    return 0; // if u want the callback to continue
}

使用CURLOPT_TIMEOUT选项?

使用CURLOPT_PROGRESSFUNCTION回调,并使操作停止当你认为它是足够的?

使用CURLOPT_LOWSPEED选项或类似选项使其依赖于传输速率

与其他建议一起使用CURLOPT_TIMEOUT,这将使您能够定义超时,您应该检查curl_easy_perform的返回值,因为它是一个阻塞调用。这里是libcurl的doc/examples/getinfo.c的一个稍微修改的版本,

#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>
int main(int argc, char* argv[])
{
  CURL *curl;
  CURLcode res;
  if (argc != 2) {
    printf("Usage: %s <timeoutInMs>n", argv[0]);
    return 1;
  }
  curl = curl_easy_init();
  curl_easy_setopt(curl, CURLOPT_URL, "http://httpbin.org/ip");
  curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, atol(argv[1]));
  res = curl_easy_perform(curl);
  if (CURLE_OK == res)
    printf("Success.n");
  else if (CURLE_OPERATION_TIMEDOUT == res)
    printf("Operation timed out.n");
  curl_easy_cleanup(curl);
  return 0;
}