【发布时间】:2015-10-06 11:36:55
【问题描述】:
最近几天,我一直在用 C# 构建一个使用 HttpListener 的 Web 服务器应用程序。我在路上学到了很多东西,现在仍然如此。目前我已经完成了所有工作,根据特定情况在这里和那里设置标题。
在大多数情况下一切正常,但有时会引发异常错误。这种情况会发生几次。大多数(如果不是全部)都在发送所有数据之前关闭连接。然后发生错误。但据我所知,其中一些确实是由浏览器引起的。
让我们以 Chrome 为例。每当我直接访问 MP3 文件时,它都会发送 2 个 GET 请求。其中一个导致错误,另一个正在工作并接收部分内容。之后,我可以听 MP3 并且没有问题。流媒体作品。 但是回到给我错误的请求,我可以在代码中使用标头中的任何内容来不输出数据,就像我已经对 HEAD 请求所做的那样。所以我在这里很困惑。
IE 在直接打开 MP3 文件和通过 HTML5 音频标签进行流式传输时也存在这个问题。它也因时而异。有时我打开页面,只发出 2 个请求。 HTML 页面和 MP3。那里没有错误。有时,有 3 个请求。它连接到 MP3 两次。现在有时其中一个连接在我打开页面后立即中止,有时对 MP3 文件的 2 个请求甚至不接受数据。在两个请求标头中,他们都希望文件结束。所以字节:123-123/124。 我还在 w3school 的音频元素上对其进行了测试。 IE 也在那里建立了两次连接,一次中止,另一次加载 MP3 文件。
所以我的问题是,是否有可能使 Web 服务器异常/防错,或者更好的问题是,抛出这些异常是不是很糟糕?或者您是否知道如何修复这些错误?
我得到的错误是:I/O 操作已被线程退出或应用程序请求中止。
我给客户写信的方式是:
using (Stream Output = _CResponse.OutputStream)
{
Output.Write(_FileOutput, rangeBegin, rangeLength);
}
我不确定是否还有其他(更好的)方法。这是我在研究时在许多主题、教程和页面中遇到的。
关于标题:默认标题:内容长度、内容类型、状态代码。在某些情况下,例如 MP3 文件和视频,我添加了 Accept-Ranges: Bytes 标头。如果请求标头中有 Range,我会添加 Content-Range 标头和 PartialContent 状态代码。
【问题讨论】:
-
不同浏览器的多次请求有什么区别?你用过 WireShark 或类似的吗?
-
不,我使用浏览器的 Inspect Element 来查看标题,有时我会读出 Request.Headers 并将结果写入控制台。成功和不成功连接之间的标头差异取决于浏览器。 Chrome 的标头几乎没有任何变化,对于成功的连接,它显示 Accept: * 。 * 和编码:身份;q=1,*;q=0。对于不成功的连接,他使用标题 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp, * / * ;q=0.8 和 Encoding: gzip, deflate, sdch。这些是 Chrome 的唯一区别。
-
对于 IE,没有什么区别,只是立即中止 2 个连接之一。有时在他想要文件末尾的 0 个字节的地方建立 2 个连接。我已经通过检查 rangeLength 是否实际上大于 0 来解决这个问题。
-
从服务器的角度来看,任何客户端都可以随时断开连接。这是服务器正常操作的一部分。检测这种特定情况,记录它并吞下异常(因为它已被处理)。这不是服务器错误。
-
@usr:好的,谢谢。这就是我想知道的。我只是不确定他们是否还好。另请阅读我上面的帖子,那里有多个请求来读取某些数据,例如大小和时间。在他们收集数据后,请求被中止。至少 2009 年的 Mozilla 就是这种情况。似乎不再是这样了,但由于某种原因它仍然在 Chrome 和 IE 中发生。
标签: c# exception httplistener