尝试发送大 zip 文件时连接被关闭
我想要完成的是允许用户从 silverlight 应用程序下载多个文件。为此,我决定使用 DotNetZip 库和 ASP.NET 处理程序来负责从数据库获取所有文件并将它们发送到客户端。这似乎是个好主意并且很容易实现。我创建了简单的处理程序,编写了所需的所有代码并且一切正常。
但是由于某种原因,当我创建包含许多文件的 zip 文件时,出现了问题。 远程主机关闭了连接。错误代码是 0x800704CD。当我尝试将数据写入
Response
时,抛出异常。
Private Sub MultipleFileDownload_Loaded(sender As Object, e As EventArgs) Handles Me.Load
// initialize data and stuff
_context.Response.Clear()
_context.Response.BufferOutput = False
Me.ZipElementsIntoOutputStream(elementsToDownload)
_context.Response.End()
End Sub
Private Sub ZipElementsIntoOutputStream(elements As List(Of ElementImageFile))
_context.Response.ContentType = "application/zip"
Dim archiveName As String = String.Format("archive-{0}.zip", DateTime.Now.ToString("yyyy-MM-dd-HHmmss"))
_context.Response.AddHeader("content-disposition", "attachment; filename=" + archiveName)
Using zip As New ZipFile()
For Each elementToDownload In elements.Where(Function(e) e IsNot Nothing AndAlso e.File IsNot Nothing)
Dim fileName = Me.GetUniqueFileName(elementToDownload, zip)
zip.AddEntry(fileName, elementToDownload.File)
Next
Using s As IO.MemoryStream = New IO.MemoryStream()
zip.Save(s)
s.Seek(0, IO.SeekOrigin.Begin)
Dim buffer(10000) As Byte
Dim length As Integer
Dim dataToRead As Long
dataToRead = s.Length
While dataToRead > 0
If (Me._context.Response.IsClientConnected) Then
length = s.Read(buffer, 0, 10000)
Me._context.Response.OutputStream.Write(buffer, 0, length)
Me._context.Response.Flush()
ReDim buffer(10000)
dataToRead = dataToRead - length
Else
dataToRead = -1
End If
End While
'zip.Save(_context.Response.OutputStream)
End Using
End Using
End Sub
正如您所看到的,我正在创建 MemoryStream
并将小块数据发送到 Response
,正如我所看到的,它是类似问题的解决方案,但这并没有帮助。将 Zip
文件直接保存到 Response
给了我完全相同的错误。
BufferOutput
属性设置为 False
,因此它会立即开始下载,但将其更改为 True
不会改变任何内容。
我尝试发送的 zip
文件大约有 248 MB,这给了我错误。当我删除一些元素并且 zip
文件大约 220 MB 时,一切似乎都工作正常。
有谁知道,这种行为的原因可能是什么?我该如何解决这个问题,这样发送 zip 文件就不会出现此错误?
What I'm trying to accomplish is to allow users to download multiple files from silverlight application. To do this I've decided to use DotNetZip
library and ASP.NET
handler that will take care of getting all files from database and sending them to client. It seemed like good idea and easy to implement. I've created simple handler, wrote all the code required and everything worked.
However for some reason, when I create zip file with many files, there is an issue. The remote host closed the connection. The error code is 0x800704CD.
exception is being thrown when I try to write data to Response
.
Private Sub MultipleFileDownload_Loaded(sender As Object, e As EventArgs) Handles Me.Load
// initialize data and stuff
_context.Response.Clear()
_context.Response.BufferOutput = False
Me.ZipElementsIntoOutputStream(elementsToDownload)
_context.Response.End()
End Sub
Private Sub ZipElementsIntoOutputStream(elements As List(Of ElementImageFile))
_context.Response.ContentType = "application/zip"
Dim archiveName As String = String.Format("archive-{0}.zip", DateTime.Now.ToString("yyyy-MM-dd-HHmmss"))
_context.Response.AddHeader("content-disposition", "attachment; filename=" + archiveName)
Using zip As New ZipFile()
For Each elementToDownload In elements.Where(Function(e) e IsNot Nothing AndAlso e.File IsNot Nothing)
Dim fileName = Me.GetUniqueFileName(elementToDownload, zip)
zip.AddEntry(fileName, elementToDownload.File)
Next
Using s As IO.MemoryStream = New IO.MemoryStream()
zip.Save(s)
s.Seek(0, IO.SeekOrigin.Begin)
Dim buffer(10000) As Byte
Dim length As Integer
Dim dataToRead As Long
dataToRead = s.Length
While dataToRead > 0
If (Me._context.Response.IsClientConnected) Then
length = s.Read(buffer, 0, 10000)
Me._context.Response.OutputStream.Write(buffer, 0, length)
Me._context.Response.Flush()
ReDim buffer(10000)
dataToRead = dataToRead - length
Else
dataToRead = -1
End If
End While
'zip.Save(_context.Response.OutputStream)
End Using
End Using
End Sub
As you can see I'm creating MemoryStream
and sending small pieces of data to Response
, as I've seen it shown as solution to similar problems, but this didn't help. Saving Zip
file directly to Response
is giving me exactly the same error.
BufferOutput
property is set to False
so it would start download immediately, but changing it to True
does not change anything.
The zip
file I'm trying to send is about 248 megabytes, and this gives me error. When I remove some elements and zip
file is around 220 megabytes, everything seems to work fine.
Does anyone knows, what might be the reason for this behavior? How can I fix this, so sending zip files will not give me this error?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实证明,问题不在
DotNetZip
和ASHX
处理程序中。问题在于传递给该处理程序的查询字符串非常长。Internet Explorer
最多可以处理查询字符串中的 2048 个字符。不幸的是我传递了更长的字符串。IE
没有给我某种错误来指示问题,而是创建了与服务器的连接,并且没有等待我的响应而是立即关闭了连接,这是导致我的问题的原因。修复查询字符串长度问题也修复了此行为,现在下载更大的文件可以正常工作。
As it turns out, the problem was not in
DotNetZip
andASHX
handler. Problem was in very long query string passed to this handler.Internet Explorer
can handle up to 2048 characters in query string. And unfortunately I passed longer string.IE
instead of giving me some kind of error to indicate the problem, created connection to server, and did not waited for my response but immediately closed connection, which was cause of my problems.Fixing query string length problem fixed also this behavior and now downloading larger files works correctly.