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

前端之家收集整理的这篇文章主要介绍了Cocos2d-x中libcurl库的使用(2)curl_easy API的介绍前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

一、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,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 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会不断调用先前设置的回调函数,用于将要上传的数据读入到缓冲区,并执行上传

猜你在找的Cocos2d-x相关文章