HTTP文件断点续传的原理
前几天一个同事跑过来找我说,我们在广告素材视频这块想做断点续传,就是这次某个视频缓存到一半,下次不用重头开始,可以在原来停留得位置开始继续下载.以提供更好的用户体验。
同时说需要我们支持吐素材地址的业务接口告诉终端最后修改时间/文件签名(md5),用这个用来判断我当前要下的文件有没有变化,同时告诉终端文件的Size大小.
我一细想,这个问题压根不需要通过改变现有接口提供更多的数据来做.下面从原理实现上简单说下:
关键点:
对于断点续传,关键点是两个:
1. 终端知道当前的文件和上一次加载的文件是不是内容发生了变化,如果有变化,需要重新从offset 0 的位置开始下载
2. 终端记录好上次成功下载到的offset,告诉server端,server端支持从特定的offset 开始吐数据
文件变化感知:
前置业务接口方案:
对于关键点1,对于决定大部分产品的业务场景,可以通过前置业务接口解决;这里简单介绍一下:
对于非下载工具类的产品,如视频APP(奇艺,优酷),视频播放前会请求相关业务的信息,主要返回片子叫什么名字,主要演员等等一些列信息,同时会返回一个对于播放最重要的信息——播放地址。
播放地址就是我们可以做文章的地方,如果《太子妃第一集》这个片子更新了(被广电要求减掉某个污的画面),可以后端系统让这个业务接口吐不同的播放地址/一个不同的url参数(?ver=1.1)/位置参数(#ver1.1)。这样纯天然的URL变化能纯天然的让终端认为不是同一个片子,而需要重新加载。
HTPP 标准ETAG方案:
没有业务接口的下载工具类的如何解决呢?
下载工具类的没有前置接口,可以使用HTTP 的ETAG来标识是否文件已经修改。
ETAG原理:如果URL上的资源内容改变,一个新的不一样的ETag就会被分配。用这种方法使用ETag即类似于指纹,并且他们能够被快速地被比较,以确定两个版本的资源是否相同。ETag的比较只对同一个URL有意义——不同URL上的资源的ETag值可能相同也可能不同,从他们的ETag的比较中无从推断。
ETAG是HTTP的一个可选字段,且没有规范他的实现;实际上业内用的比较多的就是使用MD5签名的方式来生成(linux shell md5sum)
典型用法:
server端: Nginx >1.3.3 自带有ETAG的module , 当然同时也可以在业务代码里SetHeaders加一个ETAG字段
client端:
第一次请求时:
String etag = httpURLConnection.getHeaderField("ETag");
ETag: "b428eab9654aa7c87091e"
第二次请求(断点续传时):
httpURLConnection.setRequestProperty(“If-None-Match”, "b428eab9654aa7c87091e");
If-None-Match: "b428eab9654aa7c87091e"
如果ETag值匹配,这就意味着资源没有改变,服务器便会发送回一个极短的响应,包含HTTP “304 未修改”的状态。304状态告诉客户端,它的缓存版本是最新的,并应该使用它。
然而,如果ETag的值不匹配,这就意味着资源很可能发生了变化,那么,一个完整的响应就会被返回,包括资源的内容,就好像ETag没有被使用。这种情况下,客户端可以用新返回的资源和新的ETag替代先前的缓存版本。
续传支持:
对于一个C/C++程序员,第一时间会得出一个系统级实现方案:
1. 客户端传当前的offset
2. server端seek到文件特定的offset开始读取往http connection吐数据
不过我们深处在一个开放方案和标准不断完善的时代,不需要自己实现一个(这也是像我这样的C/C++研发工程师越来越没落的原因),来看看HTTP协议是怎么解决这个问题的:
HTTP头Range字段:
Range : 用于客户端到服务器端的请求,可通过该字段指定下载文件的某一段大小,及其单位。典型的格式如:
Range: bytes=0-499 下载第0-499字节范围的内容
Range: bytes=500-999 下载第500-999字节范围的内容
Range: bytes=-500 下载最后500字节的内容
Range: bytes=500- 下载从第500字节开始到文件结束部分的内容
来个简单粗暴的例子
curl --header "Range: bytes=0-20000" xxx.com/memcache.pdf -o part1
curl --header "Range: bytes=20001-223651" xxx.com/memcache.pdf -o part2
cat part1 part2 >> a.pdf
衍生阅读:
HTTP文件断点续传的原理的更多相关文章
- 文件断点续传原理与实现—— ESFramework 通信框架4.0 进阶(12)
在ESFramework通信框架 4.0 快速上手(13) -- 文件传送,如此简单一文的详细介绍和ESFramework通信框架 4.0 快速上手(14) -- 聊天系统Demo,增加文件传送功能( ...
- .net断点续传的原理
在了解HTTP断点续传的原理之前,先来说说HTTP协议,HTTP协议是一种基于tcp的简单协议,分为请求和回复两种.请求协议是由客户机(浏览器)向服务器(WEB SERVER)提交请求时发送报文的协议 ...
- 客户端HTTP断点续传的原理
其实断点续传的原理很简单,就是在Http的请求上和一般的下载有所不同而已. 打个比方,浏览器请求服务器上的一个文时,所发出的请求如下:假设服务器域名为wwww.scu.edu.cn,文件名为down. ...
- ASP.NET用HttpListener实现文件断点续传
本文转载:http://www.cnblogs.com/TianFang/archive/2007/01/03/610739.html 断点续传的原理很简单,就是在Http的请求和应答的报文头上和一般 ...
- 浅谈文件断点续传和WebUploader的基本结合
0.写在前面的话 上篇博客已经是在8月了,期间到底发生了什么,只有我自己知道,反正就是心情特别糟糕,生活状态工作状态学习状态都十分不好,还有心思进取吗,No!现在状态好起来了,生活又充满了希望 :D ...
- PHP 实现断点续传的原理和方法
PHP 实现断点续传的原理和方法 0. http协议从1.1开始支持静态获取文件的部分内容,为多线程下载和断点续传提供了技术支持.它通过在Header里两个参数实现的,客户端发请求时对应的是Accep ...
- Linux下文件删除的原理
Linux文件删除的原理: Linux是通过link的数量来控制文件的删除的,只有当一个文件不存在任何link的时候,这个文件才会被删除,一般来说每个文件都有2个link计数器:i_count和i_n ...
- iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载+使用输出流代替文件句柄
前言:本篇讲解,在前篇iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载的基础上,使用输出流代替文件句柄实现大文件断点续传. 在实际开发中,输入输出流用的比较少,但 ...
- Spring Boot 文件上传原理
首先我们要知道什么是Spring Boot,这里简单说一下,Spring Boot可以看作是一个框架中的框架--->集成了各种框架,像security.jpa.data.cloud等等,它无须关 ...
随机推荐
- 一个App完成入门篇-终结篇(八)- 应用收官
经过以上几步的学习,我们终于来到最后一个步骤了,应用APP也接近尾声. 通过之前的几节教程,不知道您对使用DeviceOne开发一个应用是不是已经得心应手了,本节教程将教会大家如何在开发完成之后通过D ...
- Linux 服务器监控
200 ? "200px" : this.width)!important;} --> 标签:iostat/free/top/dstat 概述 文字主要讲述使用linux自带 ...
- Azure SQL Database (20) 使用SQL Server 2016 Upgrade Advisor
<Windows Azure Platform 系列文章目录> Azure SQL Database (19) Stretch Database 概览 Azure SQL Da ...
- Ubuntu 安装OpenERP
网上的都TM不靠谱.... 1.用root登录,修改/etc/apt/sources.list 文件 sudo /etc/apt/sources.list u root 注意一定要加U root否则没 ...
- JS实战 · 零碎笔记
onclick:单击时触发事件 onmouseover:鼠标进入时触发事件 onmouseout:鼠标离开时触发事件 事件三要素:最基础的内容 事件源:有监听的HTML 标签,能响应事件的HTML ...
- js array queue (队列)
前言 今天项目中做一个图片效果展示,需要实时从后台获取图片数据,前段做展示.想想用到队列,比较好实现这个功能,只需要展示队列里的数据就可以了.于是写了个js 对列. js code /** * [Qu ...
- UIwebView 和 H5交互详情
背景: 最近公司准备上一个只有原生登录界面 + H5网页 ,并且支持ios7.0 以上系统的混合app;这可把我难住了,原生的UI界面我可以正写反写各种style把界面搭建起来.而要这个app的难点在 ...
- react9 生命周期
<body><!-- React 真实 DOM 将会插入到这里 --><div id="example"></div> <!- ...
- JAVA集合
为了保存数量不确定的数据或者提供映射关系的数据,Java提供了集合类,也称作集合类,Collection和Map分别为两个根接口.两个接口体系的继承系如下图 (图片来源于网络) Collection接 ...
- margin-top失效的解决方法
异常处理汇总-前端系列 http://www.cnblogs.com/dunitian/p/4523015.html 我的是属于这种情况 按照网上的说法,我就是这个现象了 两个层box1和box2,b ...