菜鸟笔记
提升您的技术认知

http——断点续传(分块传输)-ag真人游戏

http——断点续传(分块传输)

断点续传:指的是在上传/下载时,将任务(一个文件或压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传/下载,如果碰到网络故障,可以从已经上传/下载的部分开始继续上传/下载未完成的部分,而没有必要从头开始上传/下载。可以节省时间,提高速度。

断点续传的用途
有时用户上传/下载文件需要历时数小时,万一线路中断,不具备断点续传的 http/ftp 服务器或下载软件就只能从头重传,所以如果服务器或下载软件具有断点续传能力,允许用户从上传/下载断线的地方继续传送,这样就大大减少了用户的烦恼。

在 linux/unix 系统下,常用支持断点续传的 ftp 客户端软件是 lftp

1 http1.1 之后支持端点续传

(1) range & content-range

http1.1 协议(rfc2616)开始支持获取文件的部分内容,这为并行下载以及断点续传提供了ag真人游戏的技术支持。它通过在 header 中的两个参数实现,客户端发请求时对应的是 range ,服务器端响应时对应的是 content-range

1)请求头:
range:浏览器(比如 flashget 多线程下载时)告诉 web 服务器自己想取对象的哪部分。例如:range: bytes=1173546

2)响应头
content-range:用于指定整个实体中的一部分的插入位置,他也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长度。例如,传送头500个字节次字段的形式:content-range:bytes0- 499/1234

(2)大体流程概述:

1)客户端下载一个1024k的文件,已经下载了其中512k。

2)网络中断,客户端请求续传,因此需要在http头中申明本次需要续传的片段:

range:bytes=512000-

3)服务端收到断点续传请求,从文件的512k位置开始传输,并且在http头中增加:

content-range:bytes 512000-/1024000

并且此时服务端返回的http状态码应该是206,而不是200。

206 partial content: 客户端发起了范围请求,服务器处理成功,返回了由content-range指定范围的实体内容。

2 防止续传出错

但是在实际场景中,会出现一种情况,即在终端发起续传请求时,url对应的文件内容在服务端已经发生变化,此时续传的数据肯定是错误的。如何解决这个问题了?显然此时我们需要有一个标识文件唯一性的方法。在rfc2616中也有相应的定义,比如实现last-modified来标识文件的最后修改时间,这样即可判断出续传文件时是否已经发生过改动。同时rfc2616中还定义有一个etag的头,可以使用etag头来放置文件的唯一标识,比如文件的md5值。

(1)响应头:
etag/last-modified作为标记,主要用来验证文件内容是否修改。

etag:就是一个对象(比如url)的标志值,就一个对象而言,比如一个html文件,如果被修改了,其etag也会别修改,所以,etag的作用跟last-modified的作用差不多,主要供web服务器判断一个对象是否改变了。比如前一次请求某个html文件时,获得了其 etag,当这次又请求这个文件时,浏览器就会把先前获得etag值发送给web服务器,然后web服务器会把这个etag跟该文件的当前etag进行对比,然后就知道这个文件有没有改变了。

last-modified:web服务器认为对象的最后修改时间,比如文件的最后修改时间,动态页面的最后产生时间等等。例如:last-modified:tue, 06 may 2008 02:42:43 gmt

(2)请求头:
终端在发起续传请求时应该在http头中申明if-match 或者if-modified-since 字段,帮助服务端判别文件变化。

if-modifiedsince: 如果在if-modifiedsince字段指定的日期后,资源发生了更新,服务器会接受请求。如果没有更新,即本地cache和服务器资源相同,服务器会发送一个304 not modified响应,告知本地的cache页面是最新的。

注意;
在发送http请求时,if-modified-since会把浏览器端缓存页面的最后修改时间一起发到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行比较。

  • 如果时间一致,那么返回http状态码304(不返回文件内容),客户端接到之后,就直接把本地缓存文件显示到浏览器中。
  • 如果时间不一致,就返回http状态码200和新的文件内容,客户端接到之后,会丢弃旧文件,把新文件缓存起来,并显示到浏览器中。

if-match:如果对象的 etag 没有改变,其实也就意味著对象没有改变,才执行请求的动作,获取文档。

另外rfc2616中同时定义有一个if-range头,终端如果在续传是使用if-rangeif-range中的内容可以为最初收到的etag头或者是last-modfied中的最后修改时间。服务端在收到续传请求时,通过if-range中的内容进行校验,校验一致时返回206的续传回应,不一致时服务端则返回200回应,回应的内容为新的文件的全部数据。

if-range: 浏览器告诉 web 服务器,如果我请求的对象没有改变,就把我缺少的部分给我,并返回206状态码,如果对象改变了,就把整个对象给我,并返回200。浏览器通过发送请求对象的etag 或者自己所知道的最后修改时间给 web 服务器,让其判断对象是否改变了。总是跟 range 头部一起使用。

网站地图