我已经同步使用curl
执行http请求。我的问题是如何异步进行?
我做了一些搜索,引导我查看question和example的curl_multi_*
界面的文档,但它根本没有解决任何问题。
我的简化代码:
CURLM *curlm;
int handle_count = 0;
curlm = curl_multi_init();
CURL *curl = NULL;
curl = curl_easy_init();
if(curl)
{
curl_easy_setopt(curl, CURLOPT_URL, "https://stackoverflow.com/");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl);
curl_multi_perform(curlm, &handle_count);
}
curl_global_cleanup();
回调方法writeCallback
不会被调用,也没有任何反应。
请告诉我。
修改
根据@ Remy的回答,我得到了这个,但似乎并不是我真正需要的。使用循环的原因仍然是阻塞。请告诉我,如果我做错了或误解了什么。我其实很擅长C ++。
这是我的代码:
int main(int argc, const char * argv[])
{
using namespace std;
CURLM *curlm;
int handle_count;
curlm = curl_multi_init();
CURL *curl1 = NULL;
curl1 = curl_easy_init();
CURL *curl2 = NULL;
curl2 = curl_easy_init();
if(curl1 && curl2)
{
curl_easy_setopt(curl1, CURLOPT_URL, "https://stackoverflow.com/");
curl_easy_setopt(curl1, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl1);
curl_easy_setopt(curl2, CURLOPT_URL, "http://google.com/");
curl_easy_setopt(curl2, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl2);
CURLMcode code;
while(1)
{
code = curl_multi_perform(curlm, &handle_count);
if(handle_count == 0)
{
break;
}
}
}
curl_global_cleanup();
cout << "Hello, World!\n";
return 0;
}
我现在可以同时执行2个http请求。调用回调但仍需要在执行以下行之前完成。我是否必须考虑线程?
答案 0 :(得分:8)
再次仔细阅读文档,尤其是以下部分:
http://curl.haxx.se/libcurl/c/libcurl-multi.html
当您想要调用传输数据时,您的应用程序可以从libcurl获取知识,这样您就不必忙于循环并像疯了一样调用curl_multi_perform(3)。 curl_multi_fdset(3)提供了一个界面,您可以使用该界面从libcurl中提取fd_sets以在select()或poll()调用中使用,以便了解多堆栈中的传输何时需要注意 。这也使您的程序可以很容易地同时等待您自己的私有文件描述符上的输入,或者如果您需要,可能偶尔会超时。
http://curl.haxx.se/libcurl/c/curl_multi_perform.html
当应用程序发现multi_handle的数据可用或超时已过时,应用程序应该调用此函数来读取/写入现在正在读取或写入的内容等curl_multi_perform ()在读/写完成后立即返回。此函数不要求实际上有任何可用于读取的数据或可以写入数据,可以调用它以防万一。它将写入仍然在第二个参数的整数指针中传输数据的句柄数。
如果 running_handles 的数量从上次调用中更改(或者小于您添加到多句柄的简易句柄数量),则表示您有一个或多个传输减少“跑步”。然后,您可以致电curl_multi_info_read(3)以获取有关每个已完成转移的信息,并且返回的信息包括CURLcode等。如果添加的句柄很快失败,则可能永远不会将其视为running_handle。
当此函数返回时 running_handles 设置为零(0)时,不再进行任何传输。
换句话说,你需要运行一个循环来轮询libcurl的状态,每当有数据等待传输时调用curl_multi_perform()
,根据需要重复,直到没有任何东西可以传输。
您链接的blog article提及此循环:
代码可以像
一样使用Http http;
HTTP:addRequest设置( “http://www.google.com”);//在一个称为每帧的更新循环中 HTTP:更新(); 强>
您没有在代码中进行任何循环,这就是您的回调未被调用的原因。当您拨打curl_multi_perform()
一次时,尚未收到新数据。