数据压缩

浏览器在发送请求时都会带着 Accept-Encoding 头字段,里面是浏览器支持的压缩格式列表,例如 gzip、deflate、br 等,这样服务器就可以从中选择一种压缩算法,放进 Content-Encoding 响应头里,再把原数据压缩后发给浏览器。

如果压缩率有 50%,那么 100k 的数据压完之后只剩 50k,相当于在带宽不变的情况下网速快了一倍。

这些压缩算法有一个缺点,通常只对文本文件有较好的压缩率,像图片、音频、视频等多媒体数据本身就已经是高度压缩的,再压缩不仅不会变小,还有可能变大。

分块传输

除了压缩文件之外,另一种办法就是分块传输。它们的原理差不多,都是把大文件变小传输。分块传输会把一个大文件切成很多小块,把这些小块依次发给浏览器,浏览器收到之后再组装复原。这样浏览器和服务器都不用在内存中保存全部文件,每次只收发一小部分,网络也不会被大文件长时间占用,内存、带宽等资源也就节省下来了。

具体实现是在 response 响应报文里用头字段 Transfer-Encoding: chunked 来表示,表示报文里的 body 部分不是一次性发过来的,而是分成了许多的块(chunk)逐个发送。当 chunk 为 0 时说明是最后一个,传输结束。

Transfer-Encoding 和 Content-Length 两个字段是互斥的,不能同时出现。一个响应报文的长度要么是已知的,要么是未知的。

范围请求

为什么会有范围请求?

你看电影时,想跳过开头直接看正片,这实际上是想获取一个大文件其中的片段数据,而分块传输没有这个能力。

HTTP 协议为了满足这种需求,提出了「范围请求」的概念,允许客户端在请求头里使用专用字段来表示只获取文件的一部分。

范围请求不是 Web 服务器必须实现的功能,所以服务器必须在响应头里使用字段 「Accept-Ranges: bytes 」明确告知客户端自己支持范围请求。如果不支持的话,服务器就会发送「Accept-Ranges:none」或者不发送此字段。这样客户端就只能收发整块文件了。

请求头 Range 是 HTTP 范围请求的专用字段,格式是“bytes=x-y”,其中的 x 和 y 是以字节为单位的数据范围。要注意 x、y 表示的是“偏移量”,范围必须从 0 计数,例如前 10 个字节表示为“0-9”,第二个 10 字节表示为“10-19”,而“0-10”实际上是前 11 个字节。

Range 的格式也很灵活,起点 x 和终点 y 可以省略,能够很方便地表示正数或者倒数的范围。假设文件是 100 个字节,那么:

“0-”表示从文档起点到文档终点,相当于“0-99”,即整个文件;
“10-”是从第 10 个字节开始到文档末尾,相当于“10-99”;
“-1”是文档的最后一个字节,相当于“99-99”;
“-10”是从文档末尾倒数 10 个字节,相当于“90-99”。
服务器收到 Range 字段后,需要做四件事。

第一,它必须检查范围是否合法,比如文件只有 100 个字节,但请求“200-300”,这就是范围越界了。服务器就会返回状态码 416,表示范围请求有误,无法处理。

第二,如果范围正确,服务器就可以根据 Range 头计算偏移量,读取文件的片段了,返回状态码 206 Partial Content,表示 body 只是原数据的一部分。

第三,服务器要添加一个响应头字段 Content-Range,告诉片段的实际偏移量和资源的总大小,格式是 「bytes x-y/length」,与 Range 头区别在没有“=”,范围后多了总长度。例如,对于“0-10”的范围请求,值就是“bytes 0-10/100”。

最后剩下的就是发送数据了,直接把片段用 TCP 发给客户端,一个范围请求就算是处理完了。

常用的下载工具里的多段下载、断点续传也是基于它实现的,要点是:

先发个 HEAD,看服务器是否支持范围请求,同时获取文件的大小;
开 N 个线程,每个线程使用 Range 字段划分出各自负责下载的片段,发请求传输数据;
下载意外中断不必重头再来一遍,只要根据上次的下载记录,用 Range 请求剩下的那一部分就可以了。

HTTP 如何传输大文件相关推荐

  1. JAVA实现服务器间拷贝文件,寻找在Java服务器之间传输大文件的好方法

    在这个项目中有一个主要的数据库服务器,其他安装在不同地方的服务器维护着自己的本地数据库.我们必须允许每个系统将其本地数据库更新为主要数据库上的任何版本.所有的服务器都运行Java环境.寻找在Java服 ...

  2. 局域网只看到少数电脑_利用局域网高速传输大文件的两种方法

    点击蓝字,关注我们 说到传输文件,我们可能很容易想到使用微信或者QQ发送文件,如果没有连接网络的话,可以考虑使用U盘或数据线,当然也可以使用第三方的共享文件,比如说茄子快传.以上方法的缺点自然是很明显 ...

  3. 如何快速在两台电脑之间传输大文件

    两台电脑如何传文件最快方法.我们在使用电脑的时候,有的情况下需要我们队两台电脑之间互相的传输大文件.那么我们应该通过什么样的方法传输最快速呢?我们一起来看看吧. 首先我们需要一根平时上网连接网络时用的 ...

  4. Android使用usb线传输大文件笔记

    使用usb线传输大文件 参考资料: 使用USB数据线连接PC端和Android端进行数据的交互 安卓设备通过USB接口实现与pc端的简单数据通信 Socket TCP/IP协议数据传输过程中的粘包和分 ...

  5. 为什么都说Dubbo不适合传输大文件?Dubbo支持的协议

    背景 之前公司有一个 Dubbo 服务,内部封装了腾讯云的对象存储服务 SDK,是为了统一管理这种三方服务的SDK,其他系统直接调用这个对象存储的 Dubbo 服务.用来避免因平台 SDK 出现不兼容 ...

  6. 快速传输大文件,怎么通过网络传大文件给对方(1G以上)

    在生活和工作中,我们总是要发送一些比较大的文件给别人,或者在自己的设备之间.在互联网日益发达的今天,我们可以用什么方法通过互联网快速传输大文件,发送1G以上的文件? 一.使用QQ传 在电脑上打开QQ, ...

  7. 浅析C#UDP传输大文件

    1.前言 众所周知,UDP通信是允许丢包的,这个通信方式本身就是"不太靠谱的",针对的是即便数据丢了几包也无所谓的情景,如果你非要用这个传输大文件(如一个视频),我只能说你和我一样 ...

  8. NodeJS使用socket传输大文件

    NodeJS的net模块为我们提供了socket相关API,介于此我们可以进行相关的网络编程.JavaScript 语言自身只有字符串数据类型,没有二进制数据类型,需要通过Buffer对象来处理.在这 ...

  9. 远程传输大文件使用什么平台好呢?

    远程传输大文件使用什么平台好呢?小文件倒是还可以通过QQ这样的方式进行传输,但是它对传输文件的大小有所限制,传输大文件就行不通了. 远程传输大文件使用什么平台好呢?传输大文件一个是要求传输稳定,不能说 ...

  10. 如何快速传输大文件,介绍大文件快速方法

    现在,企业比以往任何时候都面临着一个重大挑战:需要一个快速共享文件的解决方案.但是,并非所有快速文件传输解决方案都以相同的速度传输文件.文件大小.端点位置.路径.设备.防火墙.网络系统和加密需求都会限 ...

最新文章

  1. oracel 服务详细介绍
  2. matlab的7.3版本是什么_王者荣耀:玩不好元歌的3大原因,无论什么版本,元歌起码T1.5_电竞...
  3. 分享一个CSS3和jQuery实现的模糊显示效果 - 帮助你的访问用户更好的阅读内容
  4. 从0到1 | 滴滴DB自动化运维实践了解一下
  5. 2014-06-29 Web-Front的学习(5)-----DOM学习及JavaScript的扩展
  6. 简单几招提速 Kotlin Kapt编译
  7. mysql数据库集群 主主复制 原理_MySql搭建集群 之 主主复制(双主代从)MYSQL数据库...
  8. 3.5 重要的环境变量
  9. [知识库:python-tornado]异步调用中的上下文控制Tornado stack context
  10. iar c语言单片机指针,51单片机IAR编程示例
  11. 【转】赢在中国---马云点评创业精选
  12. 【暑期每日一题】洛谷 P6437 [COCI2011-2012#6] JACK
  13. 微软早就该收购雅虎了
  14. 《最强大脑》之四色定理—— GIS 无处不在
  15. php转换大小写函数,149-PHP大小写转换函数
  16. div盒模型宽高计算
  17. Python爬虫:BeautifulSoup的find()和findAll()
  18. 遥感水文前景_我国“人才紧缺”的7大专业,就业前景好,快来看看
  19. online boosting 和 batch boosting的区别
  20. albus就是要第一个出场

热门文章

  1. js获取的值传到java_使用GraalVM从javascript将变量参数传递给java函数
  2. linux解挂文件磁盘的命令,Linux学习笔记(4)磁盘分区(fdisk)、挂载与文件系统命令...
  3. Redis基础(十一)——缓存穿透和缓存雪崩
  4. 数字信号处理2:傅里叶变换
  5. sift计算描述子代码详解_浅谈SIFT特征描述子
  6. invalid comparison: java.util.Date and java.lang.String
  7. multipart/form-data;boundary=----WebKitFormBoundaryRAYPKeHKTYSNdzc1;charset=UTF-8‘ not supporte
  8. Oracle开发环境安装与使用
  9. IIS Express介绍与使用
  10. 读书笔记-大型网站技术架构