Cocos2d-x中libcurl库的使用(2)curl_easy API的介绍

来源:互联网 发布:七星彩庄家统计软件 编辑:程序博客网 时间:2024/05/17 23:04

一、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.csdn.net/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。

一般2和3是结合使用的
4)curl_easy_perform(easy_handle):执行正在的数据通信
该命令将连接到远程主机,执行必要的命令,并接收数据,当接收到数据时,之前设定的函数就会被调用,libcurl接收和返回的数据大小不一,它会尽可能多的、及时的将数据传递给回调函数,回调函数返回接收的数据长度,如果回调函数返回的长度与传递给它的长度不一致,即返回长度!=size*nmemb
libcurl将会终止操作,并返回一个错误代码。
传递结束时,curl_easy_perform将返回一个代码表示操作成功或失败,如果需要获取更多有关通信细节的信息,可以设置CURLOPT_ERRORBUFFER属性,让libcurl缓存更多可读的错误信息。

easy_handle在完成一次数据通信后可以被重用,也建议重用存在的easy_handle。

对于一些协议,下载文件可能包括许多复杂的子过程,日志记录、设置传输模式、选择当前文件夹,最后下载文件数据,使用libcurl则无需关心这些,只需一个URL。libcurl会完成所有工作。
一个简单的Demo如下:
    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的错误代码。

3、出现请求错误:可以将CURLOPT_VERBOSE属性设置为1,libcurl会输出通信过程中的一些细节,如果使用的http协议,请求头/响应头也会被输出,将CURLOPT_HEADER设置为1,这些头信息将出现在消息的内容当中。

4、上传数据到远程站点:libcurl提供协议无关的方式进行数据传输,所以上传一个文件到FTP服务器,跟向HTTP服务器提交一个PUT请求的操作方式是类似的。
1)创建easy_handle或者重用先前创建的easy_handle
2)设置CURLOPT_URL属性
3)编写回调函数。在执行的上传的时候,libcurl通过回调函数读取要上传的数据。如果要从远程服务器下载数据,可以通过回调来保存接收到的数据,上传的回调函数原型如下:
size_t  function(char* bufptr,  size_t  size,  size_t  nitems,  void*  userp);
参数1:bufptr指针表示缓冲区,用于保存要上传的数据
参数2和3:size*nitems是缓冲区数据的长度
参数4:userp是一个用户自定义指针,libcurl不对该指针作任何操作,它只是简单的传递该指针,可以使用该指针在应用程序与libcurl之间传递。
4)注册回调函数,设置自定义指针
注册回调函数:curl_easy_setopt(easy_handle, CURLOPT_READFUNCTION, read_function);
设置自定义指针:curl_easy_setopt(easy_handle, CURLOPT_READDATA, filedata);
5)告诉libcurl,执行的是上传操作。
curl_easy_setopt(easy_handle, CURLOPT_UPLOAD, 1L);
注意:有些协议在没有预先知道上传文件大小的情况下,可能无法正确判断上传是否结束,可以使用CURLOPT_INFILESIZE_LARGE属性,告诉它要上传文件的大小。
curl_easy_setopt(easy_handle, CURLOPT_INFILESIZE_LARGE, file_size);
6)调用curl_easy_perform:完成文件上传。libcurl会不断调用先前设置的回调函数,用于将要上传的数据读入到缓冲区,并执行上传。
0 0
原创粉丝点击