使用libcurl实现跨平台文件传输

 

原帖地址:http://www.cnblogs.com/just-live/archive/2012/11/04/2753236.html

 

libcurl资料:

  1. 百度百科libcurl.
  2. libcurl官方文档.

Easy  Interface:

    Easy Interface是libcurl提供的同步接口,  效率高,  容易使用, 推荐没有特殊需求的客户端应用均使用此类接口。

    Easy Interface主要接口

curl_easy_init() 
curl_easy_cleanup() 
curl_easy_setopt() 
curl_easy_perform() 
curl_easy_getinfo()

以上5个接口提供了libcurl同步操作的主要操作。

  • 使用curl_easy_init()初始化获取一个handle。
  • 使用curl_easy_setopt()设置传输选项。
  • 使用curl_easy_perform()开始传输数据,由于是同步传输,因此线程会在此处堵塞。
  • 使用curl_easy_getinfo()在传输回调过程中或传输结束之后获取相关信息。
  • 使用curl_easy_cleanup()清除handle。

使用Easy Interface实现Http GET方法的简单示例:

 
复制代码
#define CURL_BREAK_IF_NOT_OK(code)     if (code != CURLE_OK) break

size_t test_save(void *ptr, size_t size, size_t nmemb, void *stream)
{
    size_t sizes = size * nmemb;
    FILE *fp = (FILE *)(stream);
    size_t ret = 0;
    ret = fwrite(ptr,1,sizes,fp);
    assert(sizes == ret);
    return sizes;
}

int test_get(const char *url, FILE *fp)
{
    CURL *pCurl = curl_easy_init();
    int responseCode = -1;
    CURLcode returnCode = CURLE_OK;
    do 
    {
        if(!pCurl)
        {
            break;
        }
       returnCode = curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT, 10); //设置连接超时时间
        CURL_BREAK_IF_NOT_OK(returnCode);

        returnCode = curl_easy_setopt(pCurl, CURLOPT_URL, url);              //设置请求链接
        CURL_BREAK_IF_NOT_OK(returnCode);

        returnCode = curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, fp);      //设置CURLOPT_WRITEFUNCTION的最后一个参数值
        CURL_BREAK_IF_NOT_OK(returnCode);

        returnCode = curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, test_save); //设置接收到数据之后的回调函数
        CURL_BREAK_IF_NOT_OK(returnCode);

        returnCode = curl_easy_perform(pCurl);                                    //开始传输
        CURL_BREAK_IF_NOT_OK(returnCode);

        returnCode = curl_easy_getinfo(pCurl, CURLINFO_RESPONSE_CODE, &responseCode); //获取返回信息
    } while (0);
    if (pCurl) 
    {
        curl_easy_cleanup(pCurl);
    }
    return responseCode;
}
复制代码

处理在传输中途发生网络异常

    libcurl的Easy Interface使用同步, 无法像异步一样随意控制无压力,以下2种情况均可能引发curl_easy_perform阻塞卡死。

  • 下载某些大文件时,由于本地路由器流量控制,网络未断开,但是却无法接收到数据。
  • 下载过程中,网络异常中断。

解决方案:

  • 使用Multi接口。  Multi为异步接口, 牺牲了一部分效率确保了大部分灵活性,当然使用复杂度也相对上升。
  • 设置下载超时时间(CURLOPT_TIMEOUT)。设置超时时间后,curl会在超过此时间后无论正处于什么状态都会跳出堵塞,此种方案适用于小文件的下载,当然你也可以在超时之后重复连接以满足大文件的下载需求。
  • 使用回调函数返回abort value.此种方法是最简单方便的方法。一般这样操作, 1.设置进度回调函数,2. 在回调函数里面判断某个时间内有没有接收到数据,如超时返回非0值。

部分Http GET方法常用的curl_easy_setopt宏

  • CURLOPT_ERRORBUFFER 设置错误字符串buffer
  • CURLOPT_FAILONERROR >300的Http错误码不进行回写
  • CURLOPT_TIMEOUT 设置下载超时时间
  • CURLOPT_CONNECTTIMEOUT 设置连接超时时间
  • CURLOPT_URL 设置请求url
  • CURLOPT_HEADERFUNCTION 设置接收到Http头回调
  • CURLOPT_HEADERDATA 设置HEADERFUNCTION回调函数的最后一个参数
  • CURLOPT_WRITEFUNCTION 设置接收到文件内容回调
  • CURLOPT_WRITEDATA 设置WRITEFUNCTION 回调函数的最后一个参数
  • CURLOPT_PORT 设置请求端口号
  • CURLOPT_NOPROGRESS 如果需要进度回调此值必须设置为0
  • CURLOPT_PROGRESSFUNCTION 设置进度回调函数
  • CURLOPT_PROGRESSDATA 设置PROGRESSFUNCTION 回调函数的最后一个参数
  • CURLOPT_RANGE 设置请求文件偏移值 例如“1000-”表示1000字节偏移开始的所有数据
  • CURLOPT_NOBODY 不接收文件content, 一般用于实现HEAD方法

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值