Как тайм-аут вызова libcurl C ++ и / или узнать, когда произошел тайм-аут в вызове - PullRequest
7 голосов
/ 04 сентября 2011

Я пытаюсь загрузить удаленные html-страницы с помощью моей программы на C ++, однако с некоторыми 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);
    }
}

Вот моя функция для загрузки html-источника страницы в строковую переменную под названием "pageinformation" с помощью функции "writepageinformation".

Ответы [ 3 ]

4 голосов
/ 07 августа 2013
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
}
1 голос
/ 14 марта 2016

Наряду с другими предложениями по использованию CURLOPT_TIMEOUT, которые позволят вам определить время ожидания, вам нужно просто проверить возвращаемое значение curl_easy_perform, поскольку это блокирующий вызов. Вот слегка измененная версия doc / examples / getinfo.c из libcurl,

#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;
}
1 голос
/ 05 сентября 2011

Использовать опцию CURLOPT_TIMEOUT?

Воспользуйтесь обратным вызовом CURLOPT_PROGRESSFUNCTION и остановите операцию, когда вы считаете, что этого достаточно?

Используйте опцию CURLOPT_LOWSPEED или аналогичную, чтобы она зависела от скорости передачи.

...