libcurl使用easy模式阻塞卡死等问题的完美解决_第1页
libcurl使用easy模式阻塞卡死等问题的完美解决_第2页
libcurl使用easy模式阻塞卡死等问题的完美解决_第3页
libcurl使用easy模式阻塞卡死等问题的完美解决_第4页
libcurl使用easy模式阻塞卡死等问题的完美解决_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

使用 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 其中中间的参数是设置的类别 比较重要 后面会列举说明 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 中间的参数也在后面列举 必要的参数说明 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 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 downloadFileLenth getDownloadFileLenth url showTotal downloadFileLenth if localFileLenth 0 localFileLenth getLocalFileLenth filePath 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 3 断点续传 用 libcurl 实现断点续传很简单 只用两步即可实现 一是要得到本地文件已下载的大小 通过函数 getLocalFileLenth 方法来得到 二是设置 CURLOPT RESUME FROM LARGE 参数的值为已下载本地文件大 小 得到本地文件大小的函数 long getLocalFileLenth const char localPath 设置下载点如下即可 curl easy setopt handle CURLOPT RESUME FROM LARGE getLocalFileLenth localFile 三 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 就把网上建议的可以使 用的解决方法罗列 1 使用 multi 模式下载 而不使用 easy 模式 此方法的唯一好处就是 multi 并不会阻塞 而是立即返回 但是 缺点是带来了问题 其一就是需要自己去阻塞 当我们需要返回时再返回 其二还需要启动一个线程 需 要自己控制整个过程的节奏 2 在下载中 另起一个线程 若发现下载状态卡死 可以通过定期检查文件大小来实现 则从外部中断下载 线程 此方法需另起线程 而且直接中断线程 会给整个程序带来不稳定 在尝试使用网上的方法失败后 jwisp 终于设计出了自己的方案 并完美解决信号中断异常 下载中掉电异常 断点续传等问题 并且此方案不需要启动任何另外的线程 不需要手动进行阻塞 在信号中断后 恢复连接最快可 在 0 5 秒内恢复下载 并且恢复下载方式全部为断点续传 主要的设计思路如下 下载过程中 设置超时时间为 30 秒 30 秒后若下载未完成就重新连接进行下载 这个可 解决卡死问题 每次下载时进行判断 若不是首次下载则获得当前已下载文件大小 从该大小处进行续传 若网 络仍处于断开状态 再次连接会立即返回失败 此时让当前线程等待 0 5 秒后进行连接 这个可以解决瞬间恢复连 接的问题 连接次数不超过 600 次 这个用来保证 5 分钟后返回失败 掉电需要在程序已启动时检查是否上次未 下载完如果是 则直接调用下载续传方法即可 这样基本上所有的问题的流程就都能顺利走下来 并且下载过程 体验好 可随时取消 该方案主要通过两个函数来实现 一个负责进行断点续传和基本设置 并执行下载 一个负责控制整个下载 重试次数 返回下载结果 并且需要注意的是 安装完成后 应将相应的文件删除掉 源代码在下一节 四 使用 Libcurl 下载文件 解决无信号中断 下载中掉电恢复后断点续传问题的源代码 源代码附上 全局变量 bool resumeDownload false 是否需要下载的标记位 long downloadFileLenth 0 需要下载的总大小 远程文件的大小 得到本地文件大小的函数 若不是续传则返回 0 否则返回指定路径地址的文件大小 long getLocalFileLenth const char localPath if resumeDownload return 0 return fs open localPath fs size 得到远程文件的大小 要下载的文件大小 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 else downloadFileLenth 1 return downloadFileLenth scomoDownload 回调的计算进度条的函数 void getProgressValue const char localSize double dt double dn double ult double uln double showTotal showNow showTotal downloadFileLenth int localNow atoi localSize c str showNow localNow dn showProgressBar showTotal showNow 直接进行下载的函数 public CurlCode scomoDownload long timeout long localFileLenth getLocalFileLenth const char localFileLenthStr sprint localFileLenthStr ld localFileLenth curl easy setopt handle CURLOPT URL mUrl curl easy setopt handle CURLOPT HEADER 0 curl easy setopt handle CURLOPT TIMEOUT timeout curl easy setopt handle CURLOPT CONNECTIONTIMEOUT 0 curl easy setopt handle CURLOPT WRITEFUNCTION curl easy setopt handle CURLOPT WRITEDATA this curl easy setopt handle CURLOPT RESUME FROM LARGE localFileLenth curl easy setopt handle CURLOPT NOPROGRESS 0 curl easy setopt handle CURLOPT PROGRESSFUNCTION getProgressValue curl easy setopt handle CURLOPT PROGRESSDATA localFileLenthStr if curl easy perform resumeDownload true return DS FAILED else resumeDownload false return DS FINISHED downloadControl 函数用来控制整个下载过程的节奏 控制下载的次数 每次等待的时间等 public void downloadControler downloadFileLenth getDownloadFileLenth 下载前得到要下载的文件大小赋

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论