Таймаут запроса в C++
Таймаут запроса обрывает слишком долгий обмен с сервером.
Опция CURLOPT_TIMEOUT задает предел в секундах
на весь обмен, включая чтение тела. Если лимит
исчерпан, curl_easy_perform возвращает
CURLE_OPERATION_TIMEDOUT. Поставим
короткий предел и обработаем результат:
#include <iostream>
#include <string>
#include <curl/curl.h>
size_t writeBody(
char* ptr,
size_t size,
size_t nmemb,
void* userdata
) {
auto* body = static_cast<std::string*>(userdata);
body->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL* curl = curl_easy_init();
std::string body;
curl_easy_setopt(
curl,
CURLOPT_URL,
"https://example.com/"
);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeBody);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &body);
CURLcode res = curl_easy_perform(curl);
if (res == CURLE_OPERATION_TIMEDOUT) {
std::cout << "timeout\n";
} else if (res == CURLE_OK) {
std::cout << "ok\n";
}
curl_easy_cleanup(curl);
curl_global_cleanup();
return 0;
}
Щедрый лимит обычно успевает получить страницу
example.com. Сравним два значения
таймаута в одной программе:
#include <iostream>
#include <string>
#include <curl/curl.h>
size_t writeBody(
char* ptr,
size_t size,
size_t nmemb,
void* userdata
) {
auto* body = static_cast<std::string*>(userdata);
body->append(ptr, size * nmemb);
return size * nmemb;
}
void fetchWithTimeout(long seconds) {
CURL* curl = curl_easy_init();
std::string body;
curl_easy_setopt(
curl,
CURLOPT_URL,
"https://example.com/"
);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, seconds);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeBody);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &body);
CURLcode res = curl_easy_perform(curl);
if (res == CURLE_OPERATION_TIMEDOUT) {
std::cout << "timeout\n";
} else if (res == CURLE_OK) {
std::cout << "ok\n";
}
curl_easy_cleanup(curl);
}
int main() {
curl_global_init(CURL_GLOBAL_DEFAULT);
fetchWithTimeout(3L);
fetchWithTimeout(1L);
curl_global_cleanup();
return 0;
}
Отправьте чтение на "https://example.com/"
с лимитом 1 секунда. Выведите
"timeout", если сработала ошибка
по времени, иначе "ok".
Выведите "ok", если запрос к
"https://example.com/" успел завершиться
при лимите 3 секунды, и "timeout"
при более коротком лимите 1 секунда -
две строки подряд.