断点续传的原理

    其实断点续传的原理很简单,就是在Http的请求上和一般的下载有所不同而已。打个比方,浏览器请求服务器上的一个文时,所发出的请求如下:

    假设服务器域名为wwww.sjtu.edu.cn,文件名为down.zip。

GET /down.zip HTTP/1.1
    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/msword, application/vnd.ms-powerpoint, **; q=.2

    仔细看一下就会发现多了一行RANGE: bytes=2000070-;这一行的意思就是告诉服务器down.zip这个文件从2000070字节开始传,前面的字节不用传了。

 

    服务器收到这个请求以后,返回的信息如下:

  

206
    Content-Length=106786028
Content-Range=bytes 2000070-106786027/106786028
    Date=Mon, 30 Apr 2001 12:55:20 GMT
    ETag=W/"02ca57e173c11:95b"
    Content-Type=application/octet-stream
    Server=Microsoft-IIS/5.0
    Last-Modified=Mon, 30 Apr 2001 12:55:20 GMT
    和前面服务器返回的信息比较一下,就会发现增加了一行:
    Content-Range=bytes 2000070-106786027/106786028

    返回的代码也改为206了,而不再是200了。

    知道了以上原理,就可以进行断点续传的编程了。

 

HTTP头文件 status code

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html



HTTP/1.1 Range和Content-Range


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

      分割完成,每个线程都明白自己的任务,比如线程3的任务是负责下载200-299这部分文件,现在的问题是:线程3发送一个什么样的请求报文,才能够保证只请求文件的200-299字节,而不会干扰其他线程的任务。这时,我们可以使用HTTP1.1的Range头。Range头域可以请求实体的一个或者多个子范围,Range的值为0表示第一个字节,也就是Range计算字节数是从0开始的:

表示头500个字节: 
 Range: bytes=0-499 
 
    表示第二个500字节: 
 Range: bytes=500-999 
 
    表示最后500个字节: 
 Range: bytes=-500 
 
    表示500字节以后的范围: 
 Range: bytes=500- 
 
    第一个和最后一个字节: 
 Range: bytes=0-0,-1 
 
    同时指定几个范围: 
 Range: bytes=500-600,601-999 
 
所以,线程3发送的请求报文必须有这一行: 
 
     
 Range: bytes=200-299 
 

     服务器接收到线程3的请求报文,发现这是一个带有Range头的GET请求,如果一切正常,服务器的响应报文会有下面这行: 
 
HTTP/1.1 206 OK 
 
表示处理请求成功,响应报文还有这一行 
 
Content-Range: bytes 200-299/403 
 
斜杠后面的403表示文件的大小,通常Content-Range的用法为: 
 
     . The first 500 bytes: 
 
      
 Content-Range: b 
 ytes 0-499/1234 
 

     . The second 500 bytes: 
 
      
 Content-Range: bytes 500-999/1234 
 

     . All except for the first 500 bytes: 
 
      
 Content-Range: bytes 500-1233/1234 
 

     . The last 500 bytes: