libcurl模拟http访问的几点注意事项

来源:互联网 发布:云计算工程师 编辑:程序博客网 时间:2024/06/06 07:23

libcurl是一个免费开源的,客户端url传输库,支持FTPFTPSTFTPHTTPHTTPS等常见协议,跨平台,支持WindowsUnixLinux等,线程安全,支持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,则解压缩会失败

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 激素正常的多囊怎么办 右侧输卵管通而不畅怎么办 小该咳嗽老不好怎么办 孩子吓着了怎么办最快 2个月宝宝吓到了怎么办 3个月宝宝吓到了怎么办 宝宝吓着了发烧怎么办 好几个月不遗精怎么办 孕妇吃了黑橄榄怎么办 内膜4mm来月经了怎么办 吃了伟哥没效果怎么办 维a酸乳膏副作用怎么办 颈椎病引起的头晕恶心怎么办 经常头疼怎么办最快最有效 感昌了头晕乏力怎么办 来例假喝啤酒了怎么办 来月经喝啤酒了怎么办 吃的油腻长痘怎么办 兔子拉黑色稀便怎么办 宝宝补钙便秘了怎么办 吃了肾宝片上火怎么办 吃肾宝片就上火怎么办 吃肾宝片后上火怎么办 孕妇吃了扁桃仁怎么办 怀孕吃了扁桃仁怎么办 经期吃了阿胶糕怎么办 10儿童咳嗽有痰怎么办 6岁宝宝咳嗽有痰怎么办 儿童6岁咳嗽有痰怎么办 零号胶囊用多了怎么办 7岁半乳房发育,怎么办 妊娠斑怎么办,能去掉吗 跨域访问被拒绝怎么办 月子里半夜饿了怎么办 5岁儿童包茎该怎么办 6岁儿童包茎该怎么办 1岁半乳房发育,怎么办 4岁智力发育迟缓怎么办 儿童换牙长得慢怎么办 幼儿牙齿长得慢怎么办 小孩骨骼发育不好该怎么办