В соответствии с документацией функции обратного вызова работают следующим образом:
Указатель функции, который должен соответствовать следующему прототипу: функция size_t (void * ptr, size_t size, size_t nmemb, void * userdata);Эта функция вызывается libcurl, как только получаются данные, которые необходимо сохранить. Размер данных, на которые указывает ptr, равен размеру, умноженному на nmemb, он не будет завершаться нулями .Возвращает количество байтов, фактически обработанных.Если эта сумма отличается от суммы, переданной в вашу функцию, она сообщит об ошибке в библиотеку.Это прервет передачу и вернет CURLE_WRITE_ERROR.Начиная с версии 7.18.0, функция может возвращать CURL_WRITEFUNC_PAUSE, что приведет к приостановке записи в это соединение.Подробности см. В curl_easy_pause (3).
Эта функция может вызываться с нулевыми байтами данных, если переданный файл пуст.
.....
УстановитьАргумент userdata с параметром CURLOPT_WRITEDATA.
Функция обратного вызова будет передавать как можно больше данных во всех вызовах, но вы не можете делать какие-либо предположения.Это может быть один байт, это может быть тысячи.Максимальный объем данных, который может быть передан обратному вызову записи, определен в заголовочном файле curl.h: CURL_MAX_WRITE_SIZE.
Таким образом, ваш обратный вызов может вызываться много раз.Вам необходимо сохранить данные в вашей собственной структуре, которая будет отслеживать данные, прочитанные до сих пор.
Попробуйте это решение:
#include <stdio.h>
#include <curl/curl.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
size_t size;
char *payload;
}srvresponse;
size_t callback_func(void *ptr, size_t size, size_t count, void *stream) {
//printf("%s", (char*) ptr);
size_t realsize = size * count;
printf("Chuncksize:%lu\n",realsize);
srvresponse *ret = (srvresponse*)stream;
//Increase the payload size
ret->payload = realloc(ret->payload,ret->size + realsize + 1);
//Copy the new data
memcpy(&(ret->payload[ret->size]),ptr,realsize);
//Update the size
ret->size += realsize;
//Terminate the string
ret->payload[ret->size] = 0;
printf("Read so far:%s",ret->payload);
return realsize;
}
int main(void) {
CURL *curl;
srvresponse retdata;
retdata.payload = malloc(1);//We increase the capacity later
retdata.size = 0;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://stream.twitter.com/1/statuses/filter.json?track=http");
curl_easy_setopt(curl, CURLOPT_USERPWD, "user:pass");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback_func);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&retdata);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_global_cleanup();
if (retdata.payload){
puts(retdata.payload);
free(retdata.payload);
}
}
return 0;
}