libcurl模拟http访问的几点注意事项
来源:互联网 发布:云计算工程师 编辑:程序博客网 时间:2024/06/06 07:23
libcurl是一个免费开源的,客户端url传输库,支持FTP,FTPS,TFTP,HTTP,HTTPS等常见协议,跨平台,支持Windows,Unix,Linux等,线程安全,支持Ipv6。并且易于使用的函数库,http://curl.haxx.se/libcurl/
大致的使用方法如下:
curl = curl_easy_init();//初始化 if(curl){ ... curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postthis);//post的字符串 curl_easy_setopt(curl, CURLOPT_HEADER, 1);//一并获取响应头 curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip");//采用gzip压缩 curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(postthis)); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);//接收响应数据 curl_easy_setopt(curl, CURLOPT_WRITEDATA, nsp_reci); curl_easy_setopt(curl, CURLOPT_TIMEOUT,CURLTIMEOUT);//超时时间 res = curl_easy_perform(curl); if(CURLE_OK == res) { long code; curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE, &code); if(code != 200){ ... curl_easy_cleanup(curl); return false; } curl_easy_cleanup(curl);return false;} } curl_easy_cleanup(curl); }其中的write_data函数是用来接收响应的内容的
size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream) { strcat((char *)stream,ptr); //strcpy(stream,(char *)ptr); //使用strcat而不是strcpy return size*nmemb; }
很多网上的代码都是用的strcpy而不是strcat,这个在网络情况不好的时候会有问题,libcurl中这个数据接收函数会被多次调用,所以需要把数据拼接起来才是完整的响应内容,很多程序例子都忽略了这点。
倘若要上传文件和数据,可简单地参照下面的使用格式
curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "file", CURLFORM_BUFFER, filename, CURLFORM_BUFFERPTR, buffer, CURLFORM_BUFFERLENGTH, buffer_len, CURLFORM_END);这里需要注意buffer_len是一个long型数据,而不是int类型,不然在64位机器上运行libcurl的库会出现内存错误。
很多服务器支持gzip数据的传输,下面这个函数可以用于gzip数据的解压缩,测试可用,只是需要注意参数nzdata和ndata都是uLong类型的数据,传递参数时ndata需要是一个最大的uLong数字。
/* HTTP gzip decompress *//* 参数1.压缩数据 2.数据长度 3.解压数据 4.解压后长度 */int httpgzdecompress(Byte *zdata, uLong nzdata, Byte *data, uLong *ndata){ int err = 0; z_stream d_stream = {0}; /* decompression stream */ static char dummy_head[2] = { 0x8 + 0x7 * 0x10, (((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF, }; d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; d_stream.next_in = zdata; d_stream.avail_in = 0; d_stream.next_out = data; if(inflateInit2(&d_stream, 47) != Z_OK) return -1; while (d_stream.total_out < *ndata && d_stream.total_in < nzdata) { d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ if((err = inflate(&d_stream, Z_NO_FLUSH)) == Z_STREAM_END) break; if(err != Z_OK ) { if(err == Z_DATA_ERROR) { d_stream.next_in = (Bytef*) dummy_head; d_stream.avail_in = sizeof(dummy_head); if((err = inflate(&d_stream, Z_NO_FLUSH)) != Z_OK) { return -1; } } else return -1; } } if(inflateEnd(&d_stream) != Z_OK) return -1; *ndata = d_stream.total_out; return 0;}使用方法如:
int declen;httpgzdecompress((Byte *)ptr,size*nmemb,(Byte *)dec,(uLong *)&declen);
其中declen不可赋初值,因为参数转换会产生uLong类型的一个大数,这在解压缩中有用,倘若赋初值0,则解压缩会失败
- libcurl模拟http访问的几点注意事项
- webapi使用System.Web.Http.Cors配置跨域访问的几点注意事项
- 使用libcurl实现简单的HTTP访问
- 做安卓通过http访问.netmvc后台的几点体会
- SqlBulkCopy的几点注意事项
- Service的几点注意事项
- 关于HTTP的几点
- 主板维修的几点注意事项
- 预防"熊猫烧香"的几点注意事项
- sap归档项目的几点注意事项
- 有关printf函数的几点注意事项
- TD导入时的几点注意事项
- 关于C# 打包的几点注意事项
- fedora 安装 的 几点 注意事项
- 关于flashback table的几点注意事项
- MasterPage中使用的几点注意事项
- 搭建BlazeDs的几点注意事项
- Ruby test unit的几点注意事项
- shell脚本读取ini配置文件的值
- Java中将中文姓名转换为拼音的简单实现
- android系统移植emmc记录(6)--sd卡烧写文件分析
- .msc文件
- IE8下div嵌套时,外层div高度不随内层div高度改变的问题解决
- libcurl模拟http访问的几点注意事项
- D. Common Divisors CF 182D
- Java:Web应用下实现定时任务的简便方法
- 在Director中发送E-mail
- 每个程序员都该知道的10大编程格言
- STL::forward_list之前向链表
- Eclipse下导入jar包 | 架包项目通过so生成lib | Conversion to Dalvik format failed with error 1|Eclipse导出jar
- STL算法概述
- 谁在产生频率