一、curl_easy API适用于同步网络请求
1、初始化
CURL* easy_handle = curl_easy_init();
2、设置相关属性和操作curl_easy_setopt函数
使用上面初始化的easy_handle,设置相关属性与操作,其很多属性内部会自动拷贝这些字符串,curl_easy_setopt函数设置相关属性时,libcurl内部会自动拷贝这些字符串,所以设置完相关属性后,字符串可以直接释放掉。
1)CURLOPT_CURL:设置最基本最常用的属性URL
curl_easy_setopt(easy_handle,CURLOPT_URL, "http://write.blog.youkuaiyun.com/postedit");
2)CURLOPT_WRITEFUNCTION:设置回调函数获取接收到的数据
curl_easy_setopt(easy_handle,CURLOPT_WRITEFUNCTION,write_data);
假如你要获取的URL所表示的远程主机上的资源,还需要写一段程序来完成数据的传输,完成数据的保存或打印。此时需要实现一个回调函数,来保存和接收数据。其函数原型如下:
size_t write_data(void* buffer, size_t size, size_t nmemb, void* user);
参数1:传递过来的数据地址
参数2和参数3:size*nmenb表示传递数据的大小
参数4:用户用于存放数据的地址
3)CURLOPT_WRITEDATA:传递接收数据的文件地址或字符串地址
curl_easy_setopt(easy_handle,CURLOPT_WRITEDATA, &internal_struct);
从socket角度考虑,传输过来的数据不一定会是以0结尾的字符串,而应当被认为是流数据,只要服务器端没有关闭连接,就会一直发送数据响应,这个函数就会被调用,被调用的次数也不一定只是1次,每一次被调用接收的数据大小是size*nmenb,user可以是一个FILE*指针,也可以是一个字符串指针,这个参数在CURLOPT_WRITEDATA中传入,如果自己写了回调函数,而不是用缺省的回调函数把接收到得数据写到用CURLOPT_WRITEDATA所设置的userdata所指向的文件当中去,那么就可以把这个指针设置为NULL。
auto path = FileUtils::getInstance()->getWritablePath() + "data.html";
log("-------------path = %s",path.c_str());
CURLcode res;
CURL* curl_handle = curl_easy_init();
if(curl_handle)
{
FILE* fp = fopen(path.c_str(), "ab+");
char buf[128];
write_data(buf,1,128,fp);
curl_easy_setopt(curl_handle, CURLOPT_URL,"http://10.8.54.20:8080/showpageservice/queryThumbanillnfo.do");
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION,write_data);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA,fp);
res = curl_easy_perform(curl_handle);
curl_easy_cleanup(curl_handle);
fclose(fp);
if(res != CURLE_OK)
{
log("get data error");
}
}else{
log("failed to init curl");
}
size_t write_data(void *buffer,size_t size,size_t nmemb,void *user_p)
{
FILE* fp = (FILE*)user_p;
size_t return_size = fwrite(buffer, size, nmemb, fp);
log("接收到的数据:%s",buffer);
return return_size;
}
如上,注意一点是:如果文件在上面代码中打开,就要在上面代码中fclose关闭,如果在下面write_data中打开,则在下面fclose关闭,否则,libcurl会返回23的错误代码。