#curl #callback
#curl #обратный вызов
Вопрос:
Я просто следовал примеру curl multihandle, приведенному в http://curl.haxx.se/libcurl/c/multi-single.html со следующими изменениями:
- Я добавил 2 дескриптора к мультиобработке вместо одного.
- Я установил параметры
CURLOPT_WRITEDATA
иCURLOPT_WRITEFUNCTION
для обоих дескрипторов.
Предполагается, что ответы должны поступать в функцию обратного вызова write, а не в стандартный вывод. Но когда я запускаю программу, для одного дескриптора curl ответ записывается в стандартный вывод, а для другого вызывается функция обратного вызова write. Если вам интересно, ниже приведена моя полная программа. Я не просто пытаюсь опробовать примеры, я сталкиваюсь с аналогичной проблемой в моем реальном коде (только там хуже, для некоторых дескрипторов curl ответ не отправляется ни на стандартный вывод, ни на обратный вызов), поэтому это важно. Пожалуйста, помогите, пока я не застрелился. Картридж не пуст.
#include <stdio.h>
#include <string>
#include<iostream>
/* somewhat unix-specific */
#include <sys/time.h>
#include <unistd.h>
/* curl stuff */
#include <curl/curl.h>
using namespace std;
size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp) //no ordering of responses against requests maintained yet.
{
cout << "nwrite_data called with non 0 data with userp " << userp;
cout.flush();
string* stored_response = (string*)userp;
string chunk((char*)buffer,nmemb*size/sizeof(char));
stored_response->append(chunk);
return nmemb*size;
}
/*
* Simply download a HTTP file.
*/
int main(void)
{
CURL *http_handle;
CURLM *multi_handle;
int still_running; /* keep number of running handles */
http_handle = curl_easy_init();
string* response = new string("");
cout << "nresponse pointer for yahoo.com=" << response;
cout.flush();
curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, response);
curl_easy_setopt(http_handle, CURLOPT_WRITEFUNCTION, write_data);
/* set the options (I left out a few, you'll get the point anyway) */
curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.yahoo.com/");
/* init a multi stack */
multi_handle = curl_multi_init();
/* add the individual transfers */
curl_multi_add_handle(multi_handle, http_handle);
http_handle = curl_easy_init();
response = new string("");
cout << "nresponse pointer for google.com=" << response;
cout.flush();
// curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, response);
// curl_easy_setopt(http_handle, CURLOPT_WRITEFUNCTION, write_data);
/* set the options (I left out a few, you'll get the point anyway) */
curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.google.com/");
curl_multi_add_handle(multi_handle, http_handle);
/* we start some action by calling perform right away */
int multi_perform_ret;
do
{
multi_perform_ret = curl_multi_perform(multi_handle, amp;still_running);
}
while(multi_perform_ret == CURLM_CALL_MULTI_PERFORM);
while(still_running) {
cout << "nstill_running=" << still_running;
cout.flush();
struct timeval timeout;
int rc; /* select() return code */
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int maxfd = -1;
long curl_timeo = -1;
FD_ZERO(amp;fdread);
FD_ZERO(amp;fdwrite);
FD_ZERO(amp;fdexcep);
/* set a suitable timeout to play around with */
/*
timeout.tv_sec = 1;
timeout.tv_usec = 0;
curl_multi_timeout(multi_handle, amp;curl_timeo);
if(curl_timeo >= 0) {
timeout.tv_sec = curl_timeo / 1000;
if(timeout.tv_sec > 1)
timeout.tv_sec = 1;
else
timeout.tv_usec = (curl_timeo % 1000) * 1000;
}
*/
/* get file descriptors from the transfers */
curl_multi_fdset(multi_handle, amp;fdread, amp;fdwrite, amp;fdexcep, amp;maxfd);
rc = select(maxfd 1, amp;fdread, amp;fdwrite, amp;fdexcep, amp;timeout);
switch(rc) {
case -1:
/* select error */
still_running = 0;
printf("select() returns error, this is badnessn");
break;
case 0:
default:
/* timeout or readable/writable sockets */
do
{
multi_perform_ret = curl_multi_perform(multi_handle, amp;still_running);
}
while(multi_perform_ret == CURLM_CALL_MULTI_PERFORM);
break;
}
}
curl_multi_cleanup(multi_handle);
curl_easy_cleanup(http_handle);
return 0;
}
Ответ №1:
Я идиот. Я прокомментировал настройку обратного вызова для 2-го дескриптора curl.