libcurl中CURLOPT_WRITEFUNCTION设置回调函数

来源:互联网 发布:windows是一种什么系统 编辑:程序博客网 时间:2024/06/16 04:14

文档:

Let’s assume for a while that you want to receive data as the URL identifies a remote resource you want to get here. Since you write a sort of application that needs this transfer, I assume that you would like to get the data passed to you directly instead of simply getting it passed to stdout. So, you write your own function that matches this prototype:
size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp);
You tell libcurl to pass all data to this function by issuing a function similar to this:
curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, write_data);



文档只是简单的说
你可以通过设置curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, write_data)这个函数来告诉libcurl,传递所有的数据到上面的size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp);这个自己定义的满足这个格式的函数就行了。
BUT,我们来看一个例子:

#include <iostream>#include <curl/curl.h>using namespace std;size_t receive_data(void *buffer, size_t size, size_t nmemb, FILE *file);int main(){    char url[] = "http://www.sina.com.cn";    char path[] = "save_file.txt";    FILE *file = fopen(path,"w");    curl_global_init(CURL_GLOBAL_ALL);    CURL *handle = curl_easy_init();    curl_easy_setopt(handle, CURLOPT_URL, url);    curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, receive_data);    curl_easy_setopt(handle, CURLOPT_WRITEDATA, file);    cout << curl_easy_perform(handle);    curl_easy_cleanup(handle);    curl_global_cleanup();    return 0;}size_t receive_data(void *buffer, size_t size, size_t nmemb, FILE *file){    size_t r_size = fwrite(buffer, size, nmemb, file);    fclose(file);    return r_size;}

:)是不是觉得完全没有任何问题对不对,我下载了sina的html,然后保存到save_file.txt里。
BUT,当我打开save_file.txt发现里面只有不全的一段html,并没有全部在里面。为什么呢?
因为curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, receive_data);这个设置的回调函数的调用是在每次socket接收到数据之后,并不是socket接收了所有的数据,然后才调用设定的回调函数
当socket才接收到一部分数据的时候,就调用了回调函数。回调函数将接收到的不完全数据保存到文件里,然后关闭文件。然后socket又接收到了下一部分的数据,调用回调函数。但是此时文件已经被关闭了,程序出错,所以后续的内容不能够被保存到文件中。所以看到的文件也就是不完整的。

修改后的代码:

#include <iostream>#include <curl/curl.h>using namespace std;size_t receive_data(void *buffer, size_t size, size_t nmemb, FILE *file);int main() {    char url[] = "http://www.sina.com.cn";    char path[] = "save_file.txt";    FILE *file = fopen(path, "w");    curl_global_init(CURL_GLOBAL_ALL);    CURL *handle = curl_easy_init();    curl_easy_setopt(handle, CURLOPT_URL, url);    curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, receive_data);    curl_easy_setopt(handle, CURLOPT_WRITEDATA, file);    cout << curl_easy_perform(handle);    fclose(file);    curl_easy_cleanup(handle);    curl_global_cleanup();    return 0;}size_t receive_data(void *buffer, size_t size, size_t nmemb, FILE *file) {    size_t r_size = fwrite(buffer, size, nmemb, file);    return r_size;}
原创粉丝点击