架构师_程序员

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 60|回复: 2

[ASP.NET] ASP.NET用HttpListener实现文件断点续传

[复制链接]
跳转到指定楼层
楼主
发表于 2019-11-27 10:42:41
zu
断点续传的原理很简单,就是在Http的请求和应答的报文头上和一般的下载有所不同而已。
普通方式请求服务器上的一个文时,所发出的请求和接受到的服务器如下:
request header:
Cache-Control: no-cache
Connection: close
Pragma: no-cache
Accept: */*
Host: localhost
response header:
200
Content-Type: application/octet-stream
Content-Disposition: attachment;FileName=time.pdf

当服务器支持断点续传时,请求和应答如下:
request header:
Cache-Control: no-cache
Connection: close
Pragma: no-cache
Accept: */*
Host: localhost
Range: bytes=15360-
response header:
206
Content-Type: application/octet-stream
Content-Disposition: attachment;FileName=time.pdf

两个报文的不同部分已用红色部分标记出来。可以看出:
客户端报文头中通过Range报文头来标识客户期望的下载位置。
服务器的应答号为200时表示是从文件头开始下载,而206表示是从文件的特定位置开始传输,客户端从该应答号可以看出服务器是否支持断点续传。
也就是说,支持断点续传的时候可以从文件任一部分开始下载,而普通的方式只能从文件头开始下载。
要使得服务器支持断点续传,需要解决以下几个问题:

1。需要判断客户端是否是续传请求,如果是续传请求时,需要获取客户端所需的文件范围。
从上面的分析可以看到,当客户端为断点传输时,报文头里会增加Range字段,则可以通过如下方式判断是否是断点传输请求。
string range = request.Headers["Range"];
bool isResume = string.IsNullOrEmpty(range);

2。对客户端做正确的应答相应,以通知客户端服务器支持端点续传
当为断点传输请求时,对客户端的相应号可以通过如下方式设置:
response.StatusCode = 206;

3。传送客户端所需正确的内容
传送客户端所需正确的内容一般需要经过以下几个步骤
通过分析range来获取客户端的文件请求范围。
断点传输请求时,所需的长度比文件的长度短,故需要正确的设置response.ContentLength64属性。
正确传输所需的内容
代码示例:

  1. static void ProcessHttpClient(object obj)
  2. {
  3.     HttpListenerContext context = obj as HttpListenerContext;
  4.     HttpListenerRequest request = context.Request;
  5.     HttpListenerResponse response = context.Response;

  6.     FileStream fs = File.OpenRead(@"f:\123.pdf"); //待下载的文件

  7.     long startPos = 0;
  8.     string range = request.Headers["Range"];
  9.     bool isResume = string.IsNullOrEmpty(range);
  10.     if (isResume) //断点续传请求
  11.     {
  12.         //格式bytes=9216-
  13.         startPos = long.Parse(range.Split('=')[1].Split('-')[0]);
  14.         response.StatusCode = 206;
  15.         response.ContentLength64 = fs.Length - startPos;
  16.         fs.Position = startPos; //设置传送的起始位置
  17.     }
  18.     else
  19.     {
  20.         response.ContentLength64 = fs.Length;
  21.     }

  22.     Console.WriteLine("request header");
  23.     Console.WriteLine(request.Headers.ToString());

  24.     response.ContentType = "application/octet-stream";

  25.     string fileName = "time.pdf";
  26.     response.AddHeader("Content-Disposition", "attachment;FileName=" + fileName);
  27.     Stream output = response.OutputStream;

  28.     try
  29.     {
  30.         Console.WriteLine("response header");
  31.         Console.WriteLine(response.Headers.ToString());
  32.         CopyStream(fs, output); //文件传输
  33.         output.Close();
  34.     }
  35.     catch (HttpListenerException e) //在未写完所有文件时,如果客户端关闭连接,会抛此异常
  36.     {
  37.         Console.WriteLine(e.Message);
  38.         //output.Close(); //如果执行此函数会抛异常在写入所有字节之前不能关闭流。
  39.     }
  40. }

  41. static void CopyStream(Stream orgStream, Stream desStream)
  42. {
  43.     byte[] buffer = new byte[1024];

  44.     int read = 0;
  45.     while ((read = orgStream.Read(buffer, 0, 1024)) > 0)
  46.     {
  47.         desStream.Write(buffer, 0, read);

  48.         System.Threading.Thread.Sleep(1000); //模拟慢速设备
  49.     }
  50. }
复制代码





上一篇:httplistener 监听获取 Post 请求参数
下一篇:18张哲理漫画,看懂的都是高人
帖子永久地址: 

架构师_程序员 - 论坛版权1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关
2、本站所有主题由该帖子作者发表,该帖子作者与架构师_程序员享有帖子相关版权
3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和架构师_程序员的同意
4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
7、架构师_程序员管理员和版主有权不事先通知发贴者而删除本文

码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
沙发
发表于 2019-11-27 13:14:14
mark
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
回复

使用道具 举报

板凳
发表于 7 天前
marked      
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

免责声明:
码农网所发布的一切软件、编程资料或者文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:help@itsvse.com

QQ|Archiver|手机版|小黑屋|架构师 ( 鲁ICP备14021824号-2 )|网站地图

GMT+8, 2019-12-7 06:49

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表