libcurl模拟http访问的几点注意事项
libcurl是一个免费开源的,客户端url传输库,支持FTP,FTPS,TFTP,HTTP,HTTPS等常见协议,跨平台,支持Windows,Unix,Linux等,线程安全,支持Ipv6。并且易于使用的函数库,http://curl.haxx.se/libcurl/大致的使用方法如下: curl = curl_easy_init();//初始化 if(cur
·
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,则解压缩会失败
更多推荐
已为社区贡献1条内容
所有评论(0)