Http 断点续传

先说说断点续传的原理:这是HTTP 1.1协议的一部分,并不需要客户端特意去做多么复杂的事情。以前我曾经看过一个单位的技术标书,其中有下载的断点续传这一要求,给出的offer居然还挺高的...

 

简单的说,只要利用了HTTP协议http://www.ietf.org/rfc/rfc2616.txt)中的如下字段来和服务器端交互,就可以实现文件下载的断点续传:


Range : 用于客户端到服务器端的请求,可通过该字段指定下载文件的某一段大小,及其单位。典型的格式如:


Range: bytes=0-499 下载第0-499字节范围的内容
Range: bytes=500-999  下载第500-999字节范围的内容
Range: bytes=-500  下载最后500字节的内容
Range: bytes=500-  下载从第500字节开始到文件结束部分的内容(这是最常用的一种格式)
Range: bytes=0-0,-1  下载第一以及最后一个字节的内容(这个看上去有点变态...)

 

Accept-Ranges : 用于服务器端到客户端的应答,客户端通过该字段可以判断服务器是否支持断点续传(注意RFC中注明了这一部分并不是必须的)。格式如下:


Accept-Ranges: bytes  表示支持以bytes为单位进行传输。
Accept-Ranges: none  表示不支持

 

Content-Ranges : 用于服务器端到客户端的应答,与Accept-Ranges在同一个报文内,通过该字段指定了返回的文件资源的字节范围。格式如下:

Content-Ranges: bytes 0-499/1234  大小为1234的文件的第0-499字节范围的内容
Content-Ranges: bytes 734-1233/1234  大小为1234字节的文件的第734-结尾范围的内容

 

据此我们可以知道,断点续传这个功能是需要客户端和服务器端同时支持才能完成。

 

Android平台面向开发者提供了DownloadManager这个服务(service),可以用来完成下载,同时异步地得到下载进度的实时更新提示。原生的浏览器,Android Market以及GMail等客户端都使用了该接口。该接口也部分的提供了断点续传功能:如果在下载过程中遇到网络错误,如信号中断等,DownloadManager会在网络恢复时尝试断点续传继续下载该文件。但不支持由用户发起的暂停然后断点续传。

 

要扩展该功能也不难,只要为下载任务新增一种状态(类似paused_by_user),以及相关逻辑即可,这里暂不赘述,把话题引到一些常见问题上。

 

1. 关于ETag

RFC中的定义有些抽象,简单的说,ETag可以用来标识/保证文件的唯一性或完整性,你可以把它看作是服务器为某个文件生产的唯一标识值,每次文件有更新该值就会变化。通过这种机制客户端可以检查某个文件在断点续传(当然它不仅仅用于断点续传)的前后是否有所改动:如果ETag改变了就应该重新下载整个文件以保证它的完整性。

 

但是在现实环境中,有一些服务器并不返回ETag字段,同时它又是支持断点续传的,这种情况下原生的Android就会认为服务器端不支持断点续传。这应该不是什么bug,仅仅是这么实现而已。还有更麻烦的情况是,有些服务器给了错误的ETag,但文件是从未更改的,这时候要想从客户端修改这个“bug”,估计只能忽略ETag值了。

 

2. 关于HTTP 206

RFC中定义了断点续传时服务器端的应答情况:如果支持且返回的内容如请求所要求的那样,是该文件的一部分,则使用HTTP 206状态码;如果不支持,或需要返回整个文件,则使用HTTP 200状态码。但是现实网络中有些服务器不管三七二十一,都返回200。没办法,如果还是想从客户端来修改这个“bug”,那就多做一些判断处理吧:如果服务器指定了“Content-Ranges”,就忽略HTTP 200的状态码。

 

附图一张,简述流程。

 

 


补记:有一次被问起如何在原生的Android手机上暂停一个下载任务,回头再断点续传。我想是不是可以在下载过程中将手机信号关闭,下次再打开手机信号时,那个下载任务就可以自动接着续传了(当然前提是服务器支持)...这个用例没多大实用价值,懒得实测了。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

以下内容转自:http://www.android123.com.cn/androidkaifa/932.html

对于Android平台,很多网友可能考虑开发一个软件商店,对于Android平台上如何实现断点续传操作呢? 这里Android123给大家一些思路和原理的介绍,同时在Android手机上要考虑的一些事情。

  1. 流量控制,获取运营商的接入方式,比如说使用移动网络接入,尽可能的提示用户切换WiFi或提示,限制下载的流量以节省话费。

  2. 屏幕锁控制,屏幕锁屏后导致应用会被挂起,当然Android提供了PowerManager.WakeLock来控制。

  3. 对于断点续传,这要追溯到Http 1.1的特性了,主要是获取文件大小,如果这个无法读取的话,那么就无法断点续传了只能使用chunked模式了,当然获取远程服务器上文件的大小可以通过Http的响应头查找Content-Length。

  4. 获取上次文件的更改时间,对于断点续传来说比较有风险的就是 继续下载的文件和早期下载的在server上有变动,这将会导致续传时下载的文件版本和原始的不同,一般有两种解决方法,早期我们配置服务器时通过Last-Modified这个http header获取文件上次修改时间,不过本次Android开发网推荐使用更为强大的ETag,ETag一般用于解决同一个URL处理不同返回相应,比如Session认证,多国语言,以及部分黑帽的SEO中。具体的实现大家可以参考RFC文档。

  5. 考虑服务器的3xx的返回,对于专业的下载文件服务器会考虑到负载平衡问题,这就涉及到重定向问题,处理重定向使用Android的Apache库处理比较好。

  6. 至于多线程,这里CWJ提示大家可能存在独立的线程下载一个文件,和多个线程分块下载单个文件之分,其中后者需要考虑上次下载数据是否存在问题,同时如果服务器不支持文件大小获取,则无法通过分段下载数据,因为不知道如何分段,所以在chunked模式中,只能使用一个线程下载一个文件,而不是多个线程下载一个文件。

  7. 下载后的数据效验,可以考虑CRC等方式,当然对于一般的传输只要逻辑不出现问题,基本上不会有偏差。

  8. 考虑DRM问题,这个问题在国内用的比较少,而国外的受数字保护的音乐和视频,需要额外的获取证书等。

  9. 重试次数,对于一个文件可能在本次网络传输中受到问题,尤其是移动网络,所以可以设置一定的重试次数,让任务单独的走下去。

  10. 线程开发方式,这里如果你的Java基础比较好,推荐直接使用Java并发库API比较好,如果过去只做过Java开发使用Thread即可,如果Java技术不过关可以Android封装的AsyncTask。

  有关完善的多点续传的示例,Android123将在近期提供源码。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

一下内容转自:http://hi.baidu.com/lfcaolibin/blog/item/1516f1f248b733c00a46e0c7.html

实现断点续传的两种思路


实现流程

首次传输其流程如下

1.服务端向客户端传递文件名称和文件长度
2.跟据文件长度计算文件块数
3.客户端将传输的块数写入临时文件(做为断点值)
4.若文件传输成功则删除临时文件

首次传输失败后将按以下流程进行

1.客户端从临时文件读取断点值并发送给服务端
2.服务端与客户端将文件指针移至断点处
3.从断点处传输文件

这是当时的思路,但是因为当时用了CFile类实现,而不是SDK,所以我不得不重写,重写时断点续传又重新成了问题

1.下载的是文件列表
2.因为效率不再采用分块传输
3.如何记录文件列表与断点值

鉴于我以前做的断点续传,思路被禁固了一样 转不开弯  直到后来KING老大提示才饶过这个弯 其思路如下

1.客户端用CreateFile以OPEN_EXISTING方式打开要下载的文件列表
2.若成功说明有断点文件,则用GetFileSize得到大小做为断点
3若失败说明文件不存在,则创建一个文件

思路是相当简单的,而且一个好处是不用记录断点值  干净利落 呵呵
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值