代码改变世界

【iOS】Resumable Doanloads(断点下载)

2015-04-03 11:24  l4y  阅读(461)  评论(0编辑  收藏  举报

这里我们只讨论iOS平台下的通用app,我们可以自己写代码来实现resume downloads,解释如下。

resume一个HTTP下载不难,但必须要理解一些关键的HTTP概念:

  • entity tag:这是一个服务器提供的唯一的标识符,表示一个特定资源的特定版本;如果有人改变了服务器上得这个资源,entity tag会变。
  • Range header:通过这个,你可以请求一个资源指定范围内的byte。
  • If-Range header:这个表示,你想要一个资源指定范围内的bytes,如果entity tag没有改变的话。

注意:如果服务器没有提供entity tag,可以用当前时间代替。

Resuming download的基本策略如下:

  1. 如果已经初始化了下载,把与资源相关的entity tag纯起来;
  2. 当把数据存到磁盘上的时候,记住多少数据是有效的;
  3. 要resume 下载的时候,得到entity tag和已经存得数据的数量,并且把这些值给 提供Range和If-Range头的request;
  4. 执行request。成功(你收到这个资源的剩余部分),或者失败(防止你从零开始请求资源)。

一个HTTP resume request:

GET /download.info.apple.com/[...]/MacOSXUpdCombo10.6.8.dmg HTTP/1.1
Host: supportdownload.apple.com
User-Agent: Safari/7534.52.7 [...]
Accept: */*
If-Range: "968f3f3e86e0339ce722170ae656bc73:1319461845"
Range: bytes=4041400-
Accept-Language: en-au
Accept-Encoding: gzip, deflate
[...]
Connection: keep-alive

 Range头告诉服务器你想从偏移量4041400处开始得到数据。If-Range头告诉服务器,我只想在服务器的entity tag给我之后,数据没有改变的情况下,得到数据。

一个HTTP resume response:

HTTP/1.1 206 Partial Content
Server: Apache
Accept-Ranges: bytes
Content-Type: application/octet-stream
Last-Modified: Mon, 24 Oct 2011 13:04:42 GMT
ETag: "968f3f3e86e0339ce722170ae656bc73:1319461845"
Date: Mon, 23 Jan 2012 16:13:25 GMT
Content-Range: bytes 4041400-1087036999/1087037000
Content-Length: 1082995600
Connection: keep-alive

 HTTP状态码206表明response仅仅包括请求资源的一个子集(一部分),Content-Range头准确的表示了返回资源的范围(从 4041400到1087036999的字节)和资源的总长度(1087037000)。Content-Length头告诉你在这个响应中服务器返回的字节数。