如何解决Libcurl C++:向单个 URL 发送请求的非阻塞方式
目标:向同一个 URL 发送请求,而不必等待请求发送函数完成执行。
目前,当我向 URL 发送请求时,我必须等待大约 10 毫秒的服务器响应,然后才能使用相同的函数发送另一个请求。目的是检测网页上的更改比程序当前执行的速度略快,因此 WHILE 循环以非阻塞方式运行。
问题: 使用 libcurl C++,如果我有一个 WHILE 循环调用一个函数来向 URL 发送请求,我怎样才能避免在发送另一个请求之前等待函数完成执行到相同的网址?
注意:我一直在研究 libcurl 的 multi-interface
,但我正在努力确定此接口是否更适合对多个 URL 的并行请求而不是发送请求到相同的 URL,而不必每次都等待函数完成执行。我尝试了以下方法并查看了这些资源:
- 尝试使用 libcurl 请求对 C 程序进行多线程处理
- How to do curl_multi_perform() asynchronously in C++?
- 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
这是我向一个 URL 发送请求的尝试,但我必须等待 request()
函数完成并返回响应代码,然后才能再次发送相同的请求。
#include <vector>
#include <iostream>
#include <curl/curl.h>
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);
// ...
// Print variable "response"
// ...
return response_code;
}
int main() {
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl_easy_init();
while (true) {
// blocking: request() must complete before executing again
long response_code = request(curl,"https://example.com");
// ...
// Some condition breaks loop
}
curl_easy_cleanup(curl);
curl_global_cleanup();
return 0;
}
我已经尝试尽可能最好地理解 multi-interface
文档,但仍然难以完全理解它/确定它是否真的适合我的特定问题。如果这个问题似乎没有提供足够的我自己的研究,但我正在努力填补的 libcurl 知识空白,我深表歉意。
如果有人可以建议/解释我可以修改上面的单个 libcurl 示例以非阻塞方式的方式,我将不胜感激。
编辑:
来自 libcurl 的 C 实现 示例,称为“多轮询”,当我运行以下程序时,会打印 URL 的内容,但因为尽管 WHILE (1)
循环我只打印一次我很困惑它是向 URL 发送重复的非阻塞请求(这是目标),还是只是一个请求并正在等待其他一些更改/事件?
#include <stdio.h>
#include <string.h>
/* somewhat unix-specific */
#include <sys/time.h>
#include <unistd.h>
/* curl stuff */
#include <curl/curl.h>
int main(void)
{
CURL *http_handle;
CURLM *multi_handle;
int still_running = 1; /* keep number of running handles */
curl_global_init(CURL_GLOBAL_DEFAULT);
http_handle = curl_easy_init();
curl_easy_setopt(http_handle,"https://example.com");
multi_handle = curl_multi_init();
curl_multi_add_handle(multi_handle,http_handle);
while (1) {
CURLMcode mc; /* curl_multi_poll() return code */
int numfds;
/* we start some action by calling perform right away */
mc = curl_multi_perform(multi_handle,&still_running);
if(still_running) {
/* wait for activity,timeout or "nothing" */
mc = curl_multi_poll(multi_handle,NULL,1000,&numfds);
}
// if(mc != CURLM_OK) {
// fprintf(stderr,"curl_multi_wait() Failed,code %d.\n",mc);
// break;
// }
}
curl_multi_remove_handle(multi_handle,http_handle);
curl_easy_cleanup(http_handle);
curl_multi_cleanup(multi_handle);
curl_global_cleanup();
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。