当前位置:网站首页>asp.net解决大文件断点续传
asp.net解决大文件断点续传
2022-08-04 11:24:00 【51CTO】
一、概述
所谓断点续传,其实只是指下载,也就是要从文件已经下载的地方开始继续下载。在以前版本的HTTP协议是不支持断点的,HTTP/1.1开始就支持了。一般断点下载时才用到Range和Content-Range实体头。HTTP协议本身不支持断点上传,需要自己实现。
二、Range
用于请求头中,指定第一个字节的位置和最后一个字节的位置,一般格式:
Range:用于客户端到服务端的请求,可以通过改字段指定下载文件的某一段大小及其单位,字节偏移从0开始。典型格式:
Ranges: (unit=first byte pos)-[last byte pos]
Ranges: bytes=4000- 下载从第4000字节开始到文件结束部分
Ranges: bytes=0~N 下载第0-N字节范围的内容
Ranges: bytes=M-N 下载第M-N字节范围的内容
Ranges: bytes=-N 下载最后N字节内容
1.以下几点需要注意:
(1)这个数据区间是个闭合区间,起始值是0,所以“Range: bytes=0-1”这样一个请求实际上是在请求开头的2个字节。
(2)“Range: bytes=-200”,它不是表示请求文件开始位置的201个字节,而是表示要请求文件结尾处的200个字节。
(3)如果last byte pos小于first byte pos,那么这个Range请求就是无效请求,server需要忽略这个Range请求,然后回应一个200,把整个文件发给client。
(4)如果last byte pos大于等于文件长度,那么这个Range请求被认为是不能满足的,server需要回应一个416,Requested range not satisfiable。
2.示例解释:
表示头500个字节:bytes=0-499
表示第二个500字节:bytes=500-999
表示最后500个字节:bytes=-500
表示500字节以后的范围:bytes=500-
第一个和最后一个字节:bytes=0-0,-1
同时指定几个范围:bytes=500-600,601-999
三、Content-Range
用于响应头,指定整个实体中的一部分的插入位置,他也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长度。一般格式:
Content-Range: bytes (unit first byte pos) - [last byte pos]/[entity legth]
四、Header示例
请求下载整个文件:
GET /test.rar HTTP/1.1
Connection: close
Host: 116.1.219.219
Range: bytes=0-801 //一般请求下载整个文件是bytes=0- 或不用这个头
一般正常回应
HTTP/1.1 200 OK
Content-Length: 801
Content-Type: application/octet-stream
Content-Range: bytes 0-800/801 //801:文件总大小
一个最简单的断点续传实现大概如下:
1.客户端下载一个1024K的文件,已经下载了其中512K
2. 网络中断,客户端请求续传,因此需要在HTTP头中申明本次需要续传的片段:
Range:bytes=512000-
这个头通知服务端从文件的512K位置开始传输文件
3. 服务端收到断点续传请求,从文件的512K位置开始传输,并且在HTTP头中增加:
Content-Range:bytes 512000-/1024000
并且此时服务端返回的HTTP状态码应该是206,而不是200。
但是在实际场景中,会出现一种情况,即在终端发起续传请求时,URL对应的文件内容在服务端已经发生变化,此时续传的数据肯定是错误的。如何解决这个问题了?显然此时我们需要有一个标识文件唯一性的方法。在RFC2616中也有相应的定义,比如实现Last-Modified来标识文件的最后修改时间,这样即可判断出续传文件时是否已经发生过改动。同时RFC2616中还定义有一个ETag的头,可以使用ETag头来放置文件的唯一标识,比如文件的MD5值。
终端在发起续传请求时应该在HTTP头中申明If-Match 或者If-Modified-Since 字段,帮助服务端判别文件变化。
另外RFC2616中同时定义有一个If-Range头,终端如果在续传是使用If-Range。If-Range中的内容可以为最初收到的ETag头或者是Last-Modfied中的最后修改时候。服务端在收到续传请求时,通过If-Range中的内容进行校验,校验一致时返回206的续传回应,不一致时服务端则返回200回应,回应的内容为新的文件的全部数据。
相关参考链接: http://blog.ncmem.com/wordpress/2019/08/09/http%e6%96%ad%e7%82%b9%e7%bb%ad%e4%bc%a0/ 欢迎入群一起讨论:374992201
边栏推荐
- Leetcode - using sequence traversal features first completed 114. The binary tree to the list
- The use of DDR3 (Naive) in Xilinx VIVADO (2) Read and write design
- POJ1094Sorting It All Out题解
- 【机器学习】:如何对你的数据进行分类?
- 关于架构的思考
- 遍历Map的四种方法
- Leetcode brush - structure binary tree (105. Once upon a time sequence and the sequence structure binary tree traversal sequence, 106. From the sequence with the sequence structure binary tree travers
- 小程序实战(三) - head组件的封装与使用
- Camunda overall architecture and related concepts
- 【LeetCode】700.二叉搜索树
猜你喜欢
中介者模式(Mediator)
Leetcode - using sequence traversal features first completed 114. The binary tree to the list
面试蚂蚁(P7)竟被MySQL难倒,奋发图强后二次面试入职蚂蚁金服
ECCV 2022 | 清华&腾讯AI Lab提出REALY: 重新思考3D人脸重建的评估方法
[Hongke case] Assembling furniture based on 3D camera
强烈推荐一款优秀且通用的后台管理系统
audio_policy_configuration.xml配置文件详解
多表查询
ESP8266-Arduino编程实例-TSL2561亮度传感器驱动
Zikko上市同时搭载HDMI2.1和2.5GbE新款雷电4扩展坞
随机推荐
ORB-SLAM3中的优化
请 AI 画家弄了个 logo,网友热议:画得非常好,下次别画了!
*SEO*
What is the principle of thermal imaging temperature measurement?Do you know?
WPF 截图控件之画笔(八)「仿微信」
ESP8266-Arduino编程实例-APDS-9930环境光和趋近感器驱动
MySQL 45 讲 | 10 MySQL为什么有时候会选错索引?
The use of DDR3 (Naive) in Xilinx VIVADO (1) to create an IP core
win8和win10下,visual studio 2008 调试出现无响应的卡死问题解决
winform 在Datatable插入一笔数据
datax oracle to oracle incremental synchronization
入门MySql表的增删查改
Leetcode刷题——构造二叉树(105. 从前序与中序遍历序列构造二叉树、106. 从中序与后序遍历序列构造二叉树)
知网网站地址更换
数据库表列类型;DML_添加数据;DDL_修改,删除数据库表
Win11怎么重装显卡驱动程序?Win11显卡驱动怎么卸载重装?
怎么禁止textarea拉伸
【LeetCode】700.二叉搜索树
Rust 从入门到精通04-变量
linux下数据库初始化密码