如何解决C++ libcurl:使用非阻塞循环检测 HTTP 状态码变化
场景:
在预定时间更新之前,网页的 HTTP status code
为 503
。在预定时间之后将新数据添加到页面时,HTTP status code
将更改为 200
。
目标:
使用非阻塞循环,尽可能快地检测HTTP status code
从503
到200
的这种变化 >.通过下面的当前代码,WHILE
循环成功侦听 HTTP status code
中的更改并打印出成功语句。一旦检测到 200
,break 语句将停止循环。
但是,似乎程序每次发出 HTTP 请求时都必须等待响应之前移动到下一个 WHILE
循环迭代,表现为 阻塞 方式。
问题:
使用 libcurl C++,如何修改以下程序以传输请求(到单个 URL)以检测 HTTP status code
更改,而无需在发送另一个请求之前等待响应?
请注意:我知道过多的请求可能会被视为不友好(这是我自己的 URL 的实验)。
在发布此问题之前,已咨询以下 SO 问题和资源:
- How to do curl_multi_perform() asynchronously in C++?
- Is curl_easy_perform() synchronous or asynchronous?
- http://www.godpatterns.com/2011/09/asynchronous-non-blocking-curl-multi.html
- https://curl.se/libcurl/c/multi-single.html
- https://curl.se/libcurl/c/multi-poll.html
到目前为止的尝试:
- 使用多线程和
FOR
中的C
循环重复调用函数来检测 HTTP 代码更改,具有轻微的延迟优势。请参阅此处的代码:https://pastebin.com/73dBwkq3 - 再次使用
OpenMP
,当使用FOR
循环而不是原始的WHILE
循环时。延迟优势并不明显。 - 使用 libcurl 文档
C
教程尝试复制一个程序,该程序只侦听一个 URL 的更改,但使用asynchronous multi-interface
有困难。
当前尝试使用 curl_easy_opt:
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <curl/curl.h>
// Function for writing callback
size_t write_callback(char *ptr,size_t size,size_t nmemb,void *userdata) {
std::vector<char> *response = reinterpret_cast<std::vector<char> *>(userdata);
response->insert(response->end(),ptr,ptr+nmemb);
return nmemb;
}
long request(CURL *curl,const std::string &url) {
std::vector<char> response;
long response_code;
curl_easy_setopt(curl,CURLOPT_URL,url.c_str());
curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&response_code);
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,write_callback);
curl_easy_setopt(curl,CURLOPT_WRITEDATA,&response);
auto res = curl_easy_perform(curl);
if (response_code == 200) {
std::cout << "SUCCESS" << std::endl;
}
return response_code;
}
int main() {
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl_easy_init();
while (true) {
long response_code = request(curl,"www.example.com");
if (response_code == 200) {
break; // Page updated
}
}
curl_easy_cleanup(curl);
curl_global_cleanup();
return 0;
}
总结:
使用 C++
和 libcurl
,有谁知道如何使用 WHILE
循环向仅一个 URL 重复发送请求,而不必等待发送请求之间的响应?这样做的目的是尽快检测到变化。
我知道有大量的 libcurl
文档,但在掌握多界面方面以帮助将其应用于此问题时遇到了困难。
解决方法
/* get us the resource without a body - use HEAD! */
curl_easy_setopt(curl,CURLOPT_NOBODY,1L);
如果 HEAD 对您不起作用,服务器可能会拒绝 HEAD,另一种解决方案:
size_t header_callback(char *buffer,size_t size,size_t nitems,void *userdata) {
long response_code = 0;
curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&response_code);
if (response_code != 200)
return 0; // Aborts the request.
return nitems;
}
curl_easy_setopt(curl,CURLOPT_HEADERFUNCTION,header_callback);
第二种方案会消耗网络流量,HEAD好很多,收到200后就可以请求GET了。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。