asp.net 能否多线程断点续传?

在博客园上一搜就可以找到很多关于“asp.net 多线程断点续传”这方面的文章,如

http://zzk.cnblogs.com/s?w=asp.net+%e5%a4%9a%e7%ba%bf%e7%a8%8b%e6%96%ad%e7%82%b9%e7%bb%ad%e4%bc%a0&p=1

但是经过我测试,没有一个是真正实用的。

在这篇文章中(http://www.cnblogs.com/bestcomy/archive/2004/08/10/31950.html)我2007年就留言:(37楼),问题到现在还没有解决。

使用如下方法测试:

1、vs2010直接启用调试。

2、把代码编译到release版本,.NET 2.0、.NET 4.0 都有,分别发布到win2003+iis6、win2008+iis7中。

3、然后用下载软件(如网络传送带、网络蚂蚁、迅雷等)访问这个提供下载的网址,下载软件开10个任务,每个任务10线程,每个任务下载限速50K左右。

结果造成asp.net给直接挂起了!尝试访问任何aspx的页面则一直处于挂起状态,即页面无法打开,IE9选项卡的那个状态标志一直在转。

一开始以为是测试系统IE9达到最大链接数了(但是开其他第三方网站是可以的),马上在其他电脑访问也不行,状态一直挂起,甚至影响到这台服务器上的其他网站,只要是aspx的全部死掉,静态的又可以正常访问(jpg、css、js等文件),服务器的cpu和内存不占多少,几乎可忽略,下载软件停止下载后又恢复了!实在是想不出什么好方法了。

再次附上我的代码,和在博客园搜到文章上的差不多:

protected void Page_Load(object sender, EventArgs e)
{
string q = Request.QueryString.Get("q");

System.IO.FileInfo f = new System.IO.FileInfo(Server.MapPath("/") + q);

int speed = 5000;//5K

FileStream file = new FileStream(f.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryReader br = new BinaryReader(file);

Response.AddHeader("Accept-Ranges", "bytes");

Response.Buffer = false;
long fileLength = file.Length;
long startBytes = 0;

int buff = 10240; //每线程10K bytes

int sleep = 1000 * buff / speed;

if (Request.Headers["Range"] != null)
{
Response.StatusCode = 206;
string[] range = Request.Headers["Range"].Split(new char[] { '=', '-' });

startBytes = Convert.ToInt64(range[1]);
}

// 添加头信息,指定文件大小,让浏览器能够显示下载进度
Response.AddHeader("Content-Length", (fileLength - startBytes).ToString());

if (startBytes != 0)
{
//支持多线程,文件分段处理
Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength));
}

//保持链接
Response.AddHeader("Connection", "Keep-Alive");

//设置输出流数据类型。添加头信息,为"文件下载/另存为"对话框指定默认文件名
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(f.Name, System.Text.Encoding.UTF8));

//定义流的位置
br.BaseStream.Seek(startBytes, SeekOrigin.Begin);

long dataSent = fileLength - startBytes;
long dataLeft = 0;

while (dataLeft < dataSent)
{
if (Response.IsClientConnected)
{
Response.BinaryWrite(br.ReadBytes(buff));
dataLeft += buff;
Response.Flush();
Thread.Sleep(sleep);
}
else
{
dataSent = -1;
}
}
Response.End();
br.Close();
file.Close();
}

 

 

posted @ 2011-12-05 17:11 zzmsl 阅读(...) 评论(...) 编辑 收藏