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; }
倘若要上传文件和数据,可简单地参照下面的使用格式
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);