HTTP传输大文件

article/2025/8/18 20:53:51

一 概述

        早期网络传输的文件非常小,只是一些几K大小的文本和图片,随着网络技术的发展,传输的不仅有几M的图片,还有可以达到几G和几十G的视频。

        在这些大文件传输的情况下,100M的光纤或者4G移动网络都会因为网络压力导致在上传或者下载的情况下导致网络传输链路挤的“满满当当”。

二 网络中大文件传输之数据压缩

        通常浏览器在发送请求时都会带上"Accept-Encoding"头字段,该字段用来声明浏览器支持的压缩格式列表,例如gzip,deflate,br等,这样服务器就可以从中选择一种压缩算法,并将其放进"Content-Encoding"响应头中,最后将元数据压缩后发给浏览器。

        这种情况下下,如果压缩率是50%,也就是100K数据可以变成50K大小的文件进行传输,从网络的角度考虑,就类似于网络提升了一倍。

        这种方法的缺点是,gzip等压缩算法通常只是对文本文件有较好的压缩率,而图片,音频,视频的多媒体文件由于本身已经是高度压缩的,此时再使用gzip处理不会变小(甚至还有可能会增大一点),所以这种方法就不适用了。

        由于这种方法对文本类型的数据压缩效果比较好,所以大部分网站会使用该技术作为"保底"。例如,Nginx里就会使用"gzip on"指令,启用对"text/html"的压缩。

三 网络中大文件传输之数据分块传输

        相对于数据压缩那种将大文件整体变小来说,数据分块传输可以保证在大文件无法因压缩处理变小的时候,可以将其拆解,分成多个小块,然后将这些小块批发给浏览器,浏览器收到后会对拆解后的文件再进行组装复原。

        这样的好处是,在浏览器的和服务器的内存中都不会再内存中保存文件的全部,每次只是发送一小部分,从而网络不会被大文件占用,内存,宽带等资源就会被节省。

        这种"化整为零"的思路在HTTP协议里就是通过"chunked"分块传输编码,在响应报文里用头字段"Tranfer-Encoding:chunked"来表示,意思就是报文中的body部分不是一次性发送过来,而是分成许多块的"chunk"并进行逐个发送。

        分块传输也可以用于"流式数据",例如由数据库动态生成的表单页面,这种情况下body数据的长度是未知的,无法在头字段"Content-Length"里给出确切的长度,所以只能通过chunked方式分块发送。

        "Tranfer-Encodeing:chunked"和"Content-Length"这两个字段是互斥的,也就是说响应报文中的两个字段是不可以同时出现的,一个响应报文的传输长度要么已经知道了,要么是未知的(chunked)。

四 分块传输的编码规则

        分块传输的编码规则类似于响应头,同样采用了明文的方式。

  • 每个分块包含两部分,长度头和数据块。
  • 长度头是以CRLF(回车换行,即\r\n)结尾的一行明文,用16进制数字表示长度。
  • 数据块紧跟其后,最后同样使用CRLF结尾,但数据不包含CRLF。
  • 最后用一个长度为0的块(即最后的空行)来表示结束,即"0\r\n\r\n"。

        图示:

 注意:浏览器在收到分块传输的数据之后会自动按照规则去掉分块编码,重新组装出内容。

五 大文件传输之范围请求

        有了分块传输编码,服务器就可以轻松地收发大文件了,但对于上 G 的超大文件,还有一些问题需要考虑。

        比如,你在看当下正热播的某穿越剧,想跳过片头,直接看正片,或者有段剧情很无聊,想拖动进度条快进几分钟,这实际上是想获取一个大文件其中的片段数据,而分块传输并没有这个能力。

        HTTP 协议为了满足这样的需求,提出了“范围请求”(range requests)的概念,允许客户端在请求头里使用专用字段来表示只获取文件的一部分,相当于是客户端的“化整为零”。

        范围请求不是 Web 服务器必备的功能,可以实现也可以不实现,所以服务器必须在响应头里使用字段“Accept-Ranges: bytes”明确告知客户端:“我是支持范围请求的”。

        如果不支持的话该怎么办呢?服务器可以发送“Accept-Ranges: none”,或者干脆不发送“Accept-Ranges”字段,这样客户端就认为服务器没有实现范围请求功能,只能老老实实地收发整块文件了。

        请求头 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字段后的响应过程

  1.         第一,它必须检查范围是否合法,比如文件只有 100 个字节,但请求“200-300”,这就是范围越界了。服务器就会返回状态码 416,意思是“你的范围请求有误,我无法处理,请再检查一下”。
  2.         第二,如果范围正确,服务器就可以根据 Range 头计算偏移量,读取文件的片段了,返回状态码“206 Partial Content”,和 200 的意思差不多,但表示 body 只是原数据的一部分。
  3.         第三,服务器要添加一个响应头字段 Content-Range,告诉片段的实际偏移量和资源的总大小,格式是“bytes x-y/length”,与 Range 头区别在没有“=”,范围后多了总长度。例如,对于“0-10”的范围请求,值就是“bytes 0-10/100”。
  4.         最后剩下的就是发送数据了,直接把片段用 TCP 发给客户端,一个范围请求就算是处理完了。

有了范围请求之后,HTTP 处理大文件就更加轻松了,看视频时可以根据时间点计算出文件的 Range,不用下载整个文件,直接精确获取片段所在的数据内容。不仅看视频的拖拽进度需要范围请求,常用的下载工具里的多段下载、断点续传也是基于它实现的,要点是:

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

七 多段数据

        刚才说的范围请求一次只获取一个片段,其实它还支持在 Range 头里使用多个“x-y”,一次性获取多个片段数据。这种情况需要使用一种特殊的 MIME 类型:“multipart/byteranges”,表示报文的 body 是由多段字节序列组成的,并且还要用一个参数“boundary=xxx”给出段之间的分隔标记。

        多段数据的格式与分块传输也比较类似,但它需要用分隔标记 boundary 来区分不同的片段,可以通过图来对比一下。

        每一个分段必须以“- -boundary”开始(前面加两个“-”),之后要用“Content-Type”和“Content-Range”标记这段数据的类型和所在范围,然后就像普通的响应头一样以回车换行结束,再加上分段数据,最后用一个“- -boundary- -”(前后各有两个“-”)表示所有的分段结束。

参考:把大象装进冰箱:HTTP传输大文件的方法 (geekbang.org)


http://chatgpt.dhexx.cn/article/Ps0D3ywc.shtml

相关文章

使用python读取大文件

读取文件时,如果文件过大,则一次读取全部内容到内存,容易造成内存不足,所以要对大文件进行批量的读取内容。 python读取大文件通常两种方法:第一种是利用yield生成器读取;第二种是:利用open()自…

前端必学 - 大文件上传如何实现

前端必学 - 大文件上传如何实现 写在前面问题分析开始操作一、文件如何切片二、得到原文件的hash值三、文件上传四、文件合并 技术点总结【重要】一、上传文件?二、显示进度三、暂停上传四、Hash有优化空间吗?五、限制请求个数六、拥塞控制,动…

Linux如何快速生成大文件

微信搜索:“二十同学” 公众号,欢迎关注一条不一样的成长之路 dd命令 dd if/dev/zero offile bs1M count20000 会生成一个20G的file 文件,文件内容为全0(因从/dev/zero中读取,/dev/zero为0源)。 此命令可…

java 处理大文件

目的: 前几天在开发过程中遇到一个需求: 读取一个大约5G的csv文件内容,将其转化为对象然后存储到redis中, 想着直接开大内存直接load 进入到内存中就行了,结果可想而知,5G的文件 ,Xmx 开到10G都没有解决,直接out of Me…

5、Linux:如何将大文件切割成多份小文件

最近,在做数据文件的导入操作时,发现有些文本文件太大了,需要将这样的大文件切分成多个小文件进行操作。那么,Linux 中如何将大文件切割成许多的小文件呢?在此记录一下。 Linux 提供了 split 命令可以轻松实现大文件的…

大文件传输有哪些方式可用?大文件传输有哪些方式?

大文件传输有哪些方式可用?大文件传输有哪些方式?互联网时代,速度决定效率。在企业生产过程中需要进行信息数据交换、搬运。这时就需要进行大文件传输。方方面面的行业都要涉及到大文件传输。例如影视行业需要每天进行视频素材的传输&#xf…

简道云-第5章-流程

title: 简道云-第5章-流程 date: 2022-06-13 22:21:29 tags: 简道云 categories: 简道云 简道云-第5章-流程 背景介绍 简道云三个基本项目表单、流程以及仪表。关于它们的介绍可以参照官方文档表单 vs 流程表单 vs 仪表盘。 「流程表单」:填报数据,并带…

阿里云【达摩院特别版·趣味视觉AI训练营】笔记2

阿里云【趣味视觉AI训练营】笔记2 一、笔记说明二、正文2.1 人体分割实验2.2 图像人脸融合实验 三、转载说明 一、笔记说明 本博客专栏《阿里云【达摩院特别版趣味视觉AI训练营】》的所有文章均为趣味视觉AI训练营的学习笔记,当前【达摩院特别版趣味视觉AI训练营】…

笔记本简单使用eNSP的云连接外网

文章目录 前言一、连接拓扑图二、配置cloud 三、配置pc测试是否能连接外网 前言 很多时候ping不通的原因不是网卡问题,而是配置没有设置好 一、连接拓扑图 二、配置cloud 绑定信息为UDP然后点击增加 绑定信息 笔记本电脑可以选择WiFi-ip,有本地连接可以…

头歌-信息安全技术-用Python实现自己的区块链、支持以太坊的云笔记服务器端开发、编写并测试用于保存云笔记的智能合约、支持以太坊的云笔记小程序开发基础

头歌-信息安全技术-用Python实现自己的区块链、支持以太坊的云笔记服务器端开发、编写并测试用于保存云笔记的智能合约、支持以太坊的云笔记小程序开发基础 一、用Python实现自己的区块链1、任务描述2、评测步骤(1)打开终端,输入两行代码即可评测通过 二、支持以太坊…

华为云HCS解决方案笔记HUAWEI CLOUD Stack【面试篇】

目录 HCS方案 一、定义 1、特点 2、优点 二、云服务 1、云管理 2、存储服务 3、网络服务 4、计算服务 5、安全服务 6、灾备服务 7、容器服务 三、应用场景 四、HCS功能层 五、OpenStack网络平面规划 六、ManageOne运维面 1、首页 2、集中监控 3、资源拓扑 …

关于玄武集团MOS云平台的使用笔记

对于该平台感兴趣的可以自己下载开发文档看一下,附上地址: https://download.csdn.net/download/qq_39380192/11182359 1、根据开发手册,MOS云平台给用户提供了关于各种通信服务的接口,用户可以通过调用相关的接口来实现一下几点功能&#x…

巧用git commit搭建云笔记+历史记录本

一、整理笔记的必要性 长期学习过程中,我发现人脑并不擅长记忆,它更擅长思考问题。程序员每天都要学习很多知识,学得快,忘得快很正常。很多东西并不需要记住,况且知识那么多,怎么可能全部记住?…

Aliyun 学习笔记(二)阿里云物联网平台介绍

文章目录 1 阿里云物联网平台1.1 设备接入1.2 设备管理1.3 安全能力1.4 规则引擎 1 阿里云物联网平台 根据阿里云物联网平台文档可以了解到所有有关阿里云物联网平台的介绍。 阿里云物联网平台为设备提供安全可靠的连接通信能力,向下连接海量设备,支撑…

《没道云笔记》开发手记

基本配置 Client:Android Servlet:SAE(PHPMySQLStorage) Period:2 weeks 项目分析 1.Model: Article.class{int id;String username;String title;String time;String content;} Bean.calss{int[] ids;String u…

《物联网 - 机智云开发笔记》第2章 设备驱动开发

开发板:GoKit3开发板(STM32F103) 在上一章节,笔者带领大家已经将机智云平台玩起来,本节内容讲带领大家经进一步开发。 在开始讲解之前,有必要先了解的机智云的平台架构。 从上面的架构图可以看到&#xf…

云笔记的使用感受和选择

市场上有很多文章针对云笔记的选择,但经过下载发现可能存在很多虚假广告【求生欲:其实可能是个人使用感受不佳仅表示个人观点】。 为什么选择云笔记 个人比较喜欢(❤ ω ❤)记录学习笔记和生活中的东西。之前选择有道云笔记,但因为最近打开…

基于分布式的云笔记实现(参考某道云笔记)

注: 1)云笔记代码可在github上下载,如果对您有用,记得star一下。 2)依赖jar包可在以下地址下载jar包,密码:yvkj,放到web/lib下即可 3)hdfs配置参考网址 4&#xff09…

高软作业1:云笔记软件调研

写在前面: 选择云笔记作为这次调研对象,是因为看到一位同学作业里关于iOS场景下面的笔记软件对比。这一下子让我想起自己入坑过的各款云笔记应用,他们基本上都拥有云端存储和多端同步的功能,但同时又都存在着各自的优缺点。本来一…

华为云学习笔记(二)

物联网发展简史与概述 物联网大事件:NB-lot标准演进 NB-lot: 窄带物联网(Narrow Band Internet of Things, NB-IoT)成为万物互联网络的一个重要分支。NB-IoT构建于蜂窝网络,只消耗大约180kHz的带宽,可直接…