博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET用HttpListener实现文件断点续传
阅读量:6626 次
发布时间:2019-06-25

本文共 2733 字,大约阅读时间需要 9 分钟。

本文转载:

断点续传的原理很简单,就是在Http的请求和应答的报文头上和一般的下载有所不同而已。普通方式请求服务器上的一个文时,所发出的请求和接受到的服务器如下:request header:Cache-Control: no-cacheConnection: closePragma: no-cacheAccept: */*Host: localhostresponse header:200Content-Type: application/octet-streamContent-Disposition: attachment;FileName=time.pdf当服务器支持断点续传时,请求和应答如下:request header:Cache-Control: no-cacheConnection: closePragma: no-cacheAccept: */*Host: localhostRange: bytes=15360-response header:206Content-Type: application/octet-streamContent-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属性。正确传输所需的内容代码示例:static void ProcessHttpClient(object obj){    HttpListenerContext context = obj as HttpListenerContext;    HttpListenerRequest request = context.Request;    HttpListenerResponse response = context.Response;    FileStream fs = File.OpenRead(@"f:\123.pdf"); //待下载的文件    long startPos = 0;    string range = request.Headers["Range"];    bool isResume = string.IsNullOrEmpty(range);    if (isResume) //断点续传请求    {        //格式bytes=9216-        startPos = long.Parse(range.Split('=')[1].Split('-')[0]);        response.StatusCode = 206;        response.ContentLength64 = fs.Length - startPos;        fs.Position = startPos; //设置传送的起始位置    }    else    {        response.ContentLength64 = fs.Length;    }    Console.WriteLine("request header");    Console.WriteLine(request.Headers.ToString());    response.ContentType = "application/octet-stream";    string fileName = "time.pdf";    response.AddHeader("Content-Disposition", "attachment;FileName=" + fileName);    Stream output = response.OutputStream;    try    {        Console.WriteLine("response header");        Console.WriteLine(response.Headers.ToString());        CopyStream(fs, output); //文件传输        output.Close();    }    catch (HttpListenerException e) //在未写完所有文件时,如果客户端关闭连接,会抛此异常    {        Console.WriteLine(e.Message);        //output.Close(); //如果执行此函数会抛异常在写入所有字节之前不能关闭流。    }}static void CopyStream(Stream orgStream, Stream desStream){    byte[] buffer = new byte[1024];    int read = 0;    while ((read = orgStream.Read(buffer, 0, 1024)) > 0)    {        desStream.Write(buffer, 0, read);        System.Threading.Thread.Sleep(1000); //模拟慢速设备    }}

  

你可能感兴趣的文章
Javascript中函数的四种调用方式
查看>>
Java - byte[] 和 String互相转换
查看>>
win8 应用商店程序使用SQLITE数据库
查看>>
LabWindows/CVI基础
查看>>
各大OJ网址
查看>>
CentOS 5.5 字体美化之文泉驿
查看>>
HTML5离线缓存Manifest
查看>>
工作拦路虎
查看>>
python----tcp/ip http
查看>>
iOS 力学动画生成器UIKit Dynamics 之碰撞效果讲解
查看>>
Css字体中英文对照表
查看>>
jsp页面spring,fmt和c标签作用
查看>>
ubuntu下安装、启动和卸载SSH
查看>>
Android--Activity四种启动模式
查看>>
Android APK反编译就这么简单 详解(附图)
查看>>
ORACLE触发器概述之【语句触发器】【weber出品】
查看>>
LeetCode算法题-Single Number(Java实现)
查看>>
LeetCode算法题-Kth Largest Element in a Stream(Java实现)
查看>>
shell编程
查看>>
已经安装Silverlight新版本,无法安装。
查看>>