zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Asp.net中断点续传的原理与实现方法分享

NetASP方法原理 实现 分享 断点续传
2023-06-13 09:14:34 时间
请求协议是由客户机(浏览器)向服务器(WEBSERVER)提交请求时发送报文的协议。回复协议是由服务器(webserver),向客户机(浏览器)回复报文时的协议。请求和回复协议都由头和体组成。头和体之间以一行空行为分隔。
以下是一个请求报文与相应的回复报文的例子:
复制代码代码如下:

GET/image/index_r4_c1.jpgHTTP/1.1
Accept:*/*
Referer:http://192.168.3.120:8080
Accept-Language:zh-cn
Accept-Encoding:gzip,deflate
User-Agent:Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.0;.NETCLR1.0.3705)
Host:192.168.3.120:8080
Connection:Keep-Alive

HTTP/1.1200OK
Server:Microsoft-IIS/5.0
Date:Tue,24Jun200305:39:40GMT
Content-Type:image/jpeg
Accept-Ranges:bytes
Last-Modified:Thu,23May200203:05:40GMT
ETag:"bec48eb862c21:934"
Content-Length:2827
….

  顾名思义,断点续传就是在上一次下载时断开的位置开始继续下载。在HTTP协议中,可以在请求报文头中加入Range段,来表示客户机希望从何处继续下载。
  比如说从第1024字节开始下载,请求报文如下:
复制代码代码如下:


GET/image/index_r4_c1.jpgHTTP/1.1
Accept:*/*
Referer:http://192.168.3.120:8080
Accept-Language:zh-cn
Accept-Encoding:gzip,deflate
User-Agent:Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.0;.NETCLR1.0.3705)
Host:192.168.3.120:8080
Range:bytes=1024-
Connection:Keep-Alive

相应的响应报文为
复制代码代码如下:
HTTP/1.1206PartialContent
Server:Microsoft-IIS/5.0
Date:Tue,24Jun200305:39:40GMT
Content-Type:image/jpeg
Accept-Ranges:bytes
Last-Modified:Thu,23May200203:05:40GMT
ETag:"bec48eb862c21:934"
Content-Length:1803
Content-Range:bytes1024-1803/2827

通过两段不同的报文可以看到,在断点续传时,我们只要能给客户端相应相应的报文,使客户端能正确响应,并且传送续传点后的部分文件即可实现断点续传。
1.区分断点续传报文。
由于断点续传报文中含有Range字段,因此,只要通过Request.Headers["Range"]是否为null即可。
2.发送正确的续传响应报文
两次响应报文不同的部分在报文中已经用红色部分标识出来,只需修改红色部分报文头,便能发送正确的续传报文。
3.传送正确的文件部分
续传的时候只需要传送续传点之后的文件即可,首先通过请求报文中的Range字段获取文件的开始位置,传送文件的时候只需要传送该位置之后的部分即可。
下面的代码示例显示了一个可以支持断点续传的ASP.NET页
复制代码代码如下:
privatevoidPage_Load(objectsender,System.EventArgse)
{
stringfile=MapPath("ff.zip");
FileInfofi=newFileInfo(file);

longstartPos=0;

//所传输的文件长度
longfileTranLen=fi.Length;

//断点续传请求
if(Request.Headers["Range"]!=null)
{
Response.StatusCode=206;
startPos=long.Parse(Request.Headers["Range"].Replace("bytes=","").Split("-")[0]);
fileTranLen-=startPos;

//Response.AddHeader("Accept-Ranges","bytes");
//Content-Range:bytes[文件块的开始字节]-[传输文件的总大小]/[文件的总大小]
Response.AddHeader("Content-Range",string.Format("bytes{0}-{1}/{2}",startPos,fileTranLen,fi.Length));
}

Response.AddHeader("Content-Length",fileTranLen.ToString());

//基本的文件下载报文头
Response.ContentType="application/octet-stream";
Response.AddHeader("Content-Disposition","attachment;filename="+fi.Name);

//简单的流拷贝
System.IO.StreamfileStream=System.IO.File.OpenRead(file);
fileStream.Position=startPos;

byte[]buffer=newByte[1024];
intcount;
while((count=fileStream.Read(buffer,0,buffer.Length))>0)
{
Response.OutputStream.Write(buffer,0,count);
}
fileStream.Close();

Response.End();
}