断点续传和多线程下载

断点续传和多线程下载

HTTP是通过在Header里两个参数实现的,客户端发请求时对应的是Range,服务器端响应时对应的是Content-Range。

Range:客户端发请求的范围 Content-Range:服务端返回当前请求范围和文件总大小 续传成功返回206 文件又变动,返回200和新文件内容

Range 用于请求头中,指定第一个字节的位置和最后一个字节的位置,一般格式: Range:(unit=first byte pos)-[last byte pos] 1.以下几点需要注意: (1)这个数据区间是个闭合区间, 起始值是0,所以“Range: bytes=0-1”这样一个请求实际上是在请求开头的2个字节。 (2)“Range: bytes=-200”,它不是表示请求文件开始位置的201个字节,而是表示要请求文件结尾处的200个字节。 (3)如果last byte pos小于first byte pos, 那么这个Range请求就是无效请求,server需要忽略这个Range请求,然后回应一个200,把整个文件发给client。 (4)如果last byte pos大于等于文件长度, 那么这个Range请求被认为是不能满足的,server需要回应一个416,Requested range not satisfiable。

2.示例解释: 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 表示第一个和最后一个字节 Range: bytes=500-600,601-999 同时指定几个范围

Content-Range 用于响应头中,在发出带 Range 的请求后,服务器会在 Content-Range 头部返回当前接受的范围和文件总大小。一般格式: Content-Range: bytes (unit first byte pos) - [last byte pos]/[entity legth] 而在响应完成后,返回的响应头内容也不同: HTTP/1.1 200 Ok(不使用断点续传方式) HTTP/1.1 206 Partial Content(使用断点续传方式)

例如: 请求下载整个文件: GET /test.rar HTTP/1.1 Connection: close Host: 116.1.219.219 Range: bytes=0-801 //一般请求下载整个文件是bytes=0- 或不用这个头 一般正常回应 HTTP/1.1 200 OK Content-Length: 801 Content-Type: application/octet-stream Content-Range: bytes 0-800/801 //801:文件总大小

总结: HTTP1.1协议(RFC2616)中定义了断点续传相关的HTTP头 Range和Content-Range字段,一个最简单的断点续传实现大概如下: 1.客户端下载一个1024K的文件,已经下载了其中512K 2. 网络中断,客户端请求续传,因此需要在HTTP头中申明本次需要续传的片段: Range:bytes=512000- 这个头通知服务端从文件的512K位置开始传输文件 3. 服务端收到断点续传请求,从文件的512K位置开始传输,并且在HTTP头中增加: Content-Range:bytes 512000-/1024000 并且此时服务端返回的HTTP状态码应该是206,而不是200。

多线程下载: 假设你要开发一个多线程下载工具,你会自然的想到把文件分割成多个部分,比如4个部分,然后创建4个线程,每个线程负责下载一个部分,如果文件大小为403个byte,那么你的分割方式可以为:0-99 (前100个字节),100-199(第二个100字节),200-299(第三个100字节),300-402(最后103个字节)。

经验分享 程序员 微信小程序 职场和发展