我收到以下异常:

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 一起使用,还是已经缓冲了。

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

有帮助吗?

解决方案

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


即使在 2018 年,这个问题似乎也很难得到令人满意的答案,为了人性,我的两点意见是:

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

如果你像我一样,有一堆低于标准的协议代码要带入二十一世纪,那么你想要缓冲。

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

什么 BufferedStream 文档未能充分说明的是您应该 仅当您的流可查找时才切换读取和写入. 。这是因为它在同一个缓冲区中缓冲读取和写入。 BufferedStream 根本不适合 NetworkStream.

正如 Marc 指出的那样,造成这种缺陷的原因是两个流合并为一个 NetworkStream,这并不是 .net 最伟大的设计决策之一。

其他提示

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

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

A BufferedStream 只是减少对底层流(可能受 IO/硬件限制)的读/写调用的数量。它无法提供寻道功能(事实上,缓冲和寻道在很多方面是相互矛盾的)。

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

您有特定的目的吗?我也许可以建议更合适的选项和更多细节......

尤其:注意 NetworkStream 是一个好奇心 - 对于大多数流,读/写与同一个物理流相关;然而,一个 NetworkStream 实际上代表两个完全独立的管道;读和写完全无关。同样,你无法寻找已经从你身边掠过的字节......你可以 跳过 数据,但是最好通过做一些事情来完成 Read 操作并丢弃数据。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top