云题海 - 专业文章范例文档资料分享平台

当前位置:首页 > libcurl使用easy模式阻塞卡死等问题的完美解决

libcurl使用easy模式阻塞卡死等问题的完美解决

  • 62 次阅读
  • 3 次下载
  • 2025/5/2 11:55:04

使用libcurl进行文件下载类项目开发(一)libcurl简单使用介绍

引言:

由于要在android手机测进行DM开发, 其中最重要的就是FUMO和SCOMO下载, 下载使用的是linux开源库libcurl. 于是就把libcurl的使用研究了一遍, 有些心得, 并解决了一些网友的阻塞卡死问题, 于是jwisp将经验和方案分享给大家.

Libcurl使用介绍:

四个关键函数:

1. curl_easy_init()初始化curl环境, 新建curl对象, 返回对象句柄, 使用举例: CURL *handler = curl_easy_init();

2. curl_easy_setopt() 各种设置, 包括URL设置等, 使用举例:

curl_easy_setopt(handler, CURLOPT_URL, “www.http://m.njliaohua.com/”), 其中中间的参数是设置的类别, 比较重要, 后面会列举说明.

3. curl_easy_perform()开始执行下载操作, 若下载失败会返回错误码. 例如: CURLcode code = curl_easy_perform(handler)

4. curl_easy_getinfo()得到各种下载信息, 包括下载文件名, 文件大小等, 此操作必须放在curl_easy_perform()之后执行才能得到正确的值.使用举例: long resultCode;

curl_easy_getinfo(handler, CURLINFO_RESPONSE_CODE, &resultCode); 中间的参数也在后面列举 必要的参数说明

curl_easy_setopt()参数: CURLOPT_URL 设置目标URL地址

CURLOPT_HEADER 是否包含http头, 包含则设置为一个非0值

CURLOPT_NOBODY 如果你不需要http的body部分(除header头以外其他部分), 设置此项为一个非0值 CURLOPT_TIMETOU 设置一个超时时间, 若超过此时间perform会立即返回, 返回码为下载失败对应错误码, 单位秒. 注意此时间为从调用perform开始后的总的下载时间, 举例curl_easy_setopt(handler, CURLOPT_TIMEOUT, 30)

设置超时时间为30秒, 即下载必须在30秒内完成, 否则返回下载失败

CURLOPT_CONNECTIONTIMEOUT 连接超时时间, 单位秒. 这个参数在easy curl下载中基本没什么实用价值.

CURLOPT_RESUME_FROM_LARGE从什么位置开始下载, 断点续传主要使用此参数进行配置, 使用非常简单, 只需要传递一个字节偏移量即可, 例如

curl_easy_setopt(handler, CURLOPT_RESUME_FROM, 0), 表示从第0个字节开始下载, curl_easy_setopt(handler, CURLOPT_RESUME_FROM, 500), 从第500个字节开始下载

CURLOPT_RANGE 下载指定字节的文件块, 参数对应的值格式为X-Y, 例如curl_easy_setopt(handler, CURLOPT_RESUME_FROM, “500-999”), 下载从500个字节开始到999字节结束的文件块

CURLOPT_NOPROGRESS 如果不需要下载进度设置此项为一个非0值

CURLOPT_PROGRESSFUNCTION 设置回调的进度函数, 设置后, 会不断的调用进度函数, 并传递参数总大小和已下载大小给该函数

CURLOPT_PROGRESSDATA 设置传递给回调的进度函数的一个参数, 类型为字符串类型, 后面jwisp会举例说明

curl_easy_getinfo() 部分参数说明

CURLINFO_RESPONSE_CODE 得到perform的执行结果码 CURLINFO_CONTENT_LENGTH_DOWNLOAD 得到下载文件大小

下一节为大家介绍, 如何使用这些libcurl函数进行文件大小的获取, 下载进度显示和断点续传.

(二)使用libcurl实现获取目标文件大小,下载进度显示, 断点续传等功能

本节jwisp为大家举例说明如果使用上节介绍的函数和参数, 在使用libcurl的过程中, 如何获取下载目标文件的大小, 下载进度条, 断点续传等, 这些基本的函数, 将为jwisp在最后处理下载过程异常中断等问题提供支持.

1. 编写得到下载目标文件的大小的函数 long getDownloadFileLenth(const char *url){

long downloadFileLenth = 0; CURL *handle = curl_easy_init();

curl_easy_setopt(handle, CURLOPT_URL, url);

curl_easy_setopt(handle, CURLOPT_HEADER, 1); //只需要header头 curl_easy_setopt(handle, CURLOPT_NOBODY, 1); //不需要body if (curl_easy_perform(handle) == CURLE_OK) {

curl_easy_getinfo(handle,CURLINFO_CONTENT_LENGTH_DOWNLOAD,&downloadFileLenth); } else {

downloadFileLenth = -1;

}

return downloadFileLenth; }

2. 下载中回调自己写的得到下载进度值的函数 下载回调函数的原型应该为:

int progressFunc(const char* flag, double dtotal, double dnow, double ultotal, double ulnow); a. 应该在外部声明一个远程下载文件大小的全局变量 double downloadFileLenth = 0;

为了断点续传, 还应该声明一个本地文件大小的全局变量 double localFileLenth = 0;

b. 编写一个得到进度值的函数getProgressValue()

int getProgressValue(const char* flag, double dt, double dn, double ult, double uln){

double showTotal, showNow; if (downloadFileLenth == 0){ }

showTotal = downloadFileLenth;

if (localFileLenth == 0){ }

showNow = localFileLenth + dn;

//然后就可以调用你自己的进度显示函数了, 这里假设已经有一个进度函数, 那么只需要传递当前下载值和总下载值即可.

showProgressValue(showNow, showTotal); }

c. 在下载中进行三个下载参数的设置

curl_easy_setopt(handle, CURLOPT_NOPROGRESS, 0);

curl_easy_setopt(handle, CURLOPT_PROGRESSFUNCTION, getProgressValue); //设置回调的进度函数 curl_easy_setopt(handle, CURLOPT_PROGRESSDATA, “flag”); //此设置对应上面的const char *flag

localFileLenth = getLocalFileLenth(filePath); downloadFileLenth = getDownloadFileLenth(url);

3. 断点续传

用libcurl实现断点续传很简单, 只用两步即可实现, 一是要得到本地文件已下载的大小, 通过函数getLocalFileLenth()方法来得到, 二是设置CURLOPT_RESUME_FROM_LARGE参数的值为已下载本地文件大小.

得到本地文件大小的函数:

==========================================================================================

(三)Libcurl中使用curl_easy_perform阻塞, 遇到无信号卡死的完美解决方案 项目背景:

近来jwisp在做OMA-DM的android终端侧, 要实现的功能包括FUMO, SCOMO下载管理. 由于项目是基于funambol的开源代码, 在实现FUMO和SCOMO时, 使用了libcurl的库来实现下载服务测的指定文件, 下载后实现android固件升级或android应用下载安装功能, 最后将FUMO/SCOMO的下载安装结果上报给服务端. 需求背景:

下载流程比较简单, 使用curl_easy_perform即可实现完整的下载流程, 安装后, 使用OMA DM协议上报给平台侧.但是jwisp这里的需求还有两个异常情况需要处理:

1. 下载过程中, 遇手机突然掉电(操作:扣电池), android终端再次启动后应能恢复现场然后自动下载, 下载

方式为建议断点续传

2. 下载过程中信号中断, 中断时间在5分钟之内, 终端应尝试重新连接, 连接次数在3次以上. 重新连接

后建议使用断点续传方式继续下载.

但是在使用libcurl时, jwisp发现, curl_easy_perform是阻塞的方式进行下载的, curl_easy_perform执行后, 程序会在这里阻塞等待下载结束(成功结束或者失败结束).此时若正常下载一段时间后, 进行网络中断, curl_easy_perform并不会返回失败, 而是阻塞整个程序卡在这里, 此时即使网络连接重新恢复, curl_easy_perform也无法恢复继续下载, 导致整个程序出现”死机”状态.

但是若先断网, 然后进行curl_easy_perform的话, 会直接返回失败, 不会阻塞

在网上搜索后发现, 大家在网上遇到这个问题的很多, 但是解决方法很少, 下面jwisp就把网上建议的可以使

long getLocalFileLenth(const char* localPath);

设置下载点如下即可:

curl_easy_setopt(handle, CURLOPT_RESUME_FROM_LARGE, getLocalFileLenth(localFile));

  • 收藏
  • 违规举报
  • 版权认领
下载文档10.00 元 加入VIP免费下载
推荐下载
本文作者:...

共分享92篇相关文档

文档简介:

使用libcurl进行文件下载类项目开发(一)libcurl简单使用介绍 引言: 由于要在android手机测进行DM开发, 其中最重要的就是FUMO和SCOMO下载, 下载使用的是linux开源库libcurl. 于是就把libcurl的使用研究了一遍, 有些心得, 并解决了一些网友的阻塞卡死问题, 于是jwisp将经验和方案分享给大家. Libcurl使用介绍: 四个关键函数: 1. curl_easy_init()初始化curl环境, 新建curl对象, 返回对象句柄, 使用举例: CURL *handler = curl_easy_init(); 2. curl_easy_setopt() 各种设置, 包括URL设置等, 使用举例: curl_easy_

× 游客快捷下载通道(下载后可以自由复制和排版)
单篇付费下载
限时特价:10 元/份 原价:20元
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:fanwen365 QQ:370150219
Copyright © 云题海 All Rights Reserved. 苏ICP备16052595号-3 网站地图 客服QQ:370150219 邮箱:370150219@qq.com