2

我收到以下异常:

System.NotSupportedException : This stream does not support seek operations.
   at System.Net.Sockets.NetworkStream.Seek(Int64 offset, SeekOrigin origin)
   at System.IO.BufferedStream.FlushRead()
   at System.IO.BufferedStream.WriteByte(Byte value)

以下链接显示这是微软的一个已知问题。 http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=273186

这个堆栈跟踪显示了两件事:

  1. System.IO.BufferedStream 做了一些荒谬的指针移动操作。BufferedStream 应该缓冲底层流而不是更多。如果有这样的查找操作,缓冲区的质量会很差。
  2. 对于不支持 Seek 的流,它永远不会稳定工作。

有没有其他选择?我需要一个缓冲区和 C# 中的 NetworkStream 还是已经缓冲了。

编辑:我只想减少对底层套接字流的读/写调用次数。

4

3 回答 3

2

NetworkStream 已被缓冲。接收到的所有数据都保存在缓冲区中,等待您读取。读取调用要么非常快,要么会阻塞等待从网络上的其他对等方接收数据,无论哪种情况,BufferedStream 都无济于事。

如果您担心阻塞,那么您可以考虑将底层套接字切换到非阻塞模式。

于 2009-02-15T20:44:45.127 回答
1

A 的BufferedStream作用是减少对底层流(可能是 IO/硬件绑定)的读/写调用次数。它不能提供搜索功能(实际上,缓冲和搜索在许多方面是相互矛盾的)。

为什么需要寻求?也许首先将流复制到可搜索的东西 - aMemoryStream或 a FileStream- 然后从第二个可搜索的流中进行实际工作。

你有一个特定的目的吗?我也许可以建议更合适的选项,并提供更多详细信息...

特别是:请注意这NetworkStream是一个好奇心 - 对于大多数流,读/写与相同的物理流相关;但是,aNetworkStream实际上代表两个完全独立的管道;读和写完全不相关。同样,您不能在已经压缩过去的字节中寻找......您可以跳过数据,但最好通过执行一些Read操作并丢弃数据来完成。

于 2009-02-15T20:02:39.690 回答
1

解决方案是使用两个独立BufferedStream的s,一个用于接收,一个用于发送。并且不要忘记BufferedStream适当地刷新发送。


因为即使在 2018 年,似乎也很难得到一个令人满意的答案,为了人性,这里是我的两分钱:

在操作系统NetworkStream 缓冲。但是,这并不意味着没有理由在 .net 端进行缓冲。TCP 在 Write-Read(重复)上表现良好,但由于延迟 ack 等原因,在 Write-Write-Read 上停滞不前。

如果你和我一样,有一堆低于标准的协议代码要带入 21 世纪,你想缓冲一下。

或者,如果您坚持上述做法,您也可以仅缓冲读取/rcvs 或仅写入/发送,并NetworkStream直接将其用于另一端,具体取决于代码的损坏程度。你只需要保持一致!

BufferedStream文档未能充分说明的是,如果您的流是可搜索的,您应该只切换阅读和写作。这是因为它在同一个缓冲区中缓冲读取和写入。BufferedStream根本不适合NetworkStream

正如 Marc 所指出的,这种跛行的原因是将两个流合并为一个 NetworkStream,这不是 .net 最伟大的设计决策之一。

于 2018-10-04T10:20:59.660 回答