我正在从事一个涉及通过 TCP 和 Google Protocol Buffer 进行客户端服务器通信的项目。在客户端,我基本上使用 NetworkStream.Read() 通过字节数组缓冲区阻止从服务器读取。

根据 MSDN 文档,



异步读取(NetworkStream.BeginRead 和 EndRead)也是如此。我的问题是 Read()/EndRead() 什么时候返回?看起来它会在缓冲区中的所有字节都填满后返回。但在我自己的测试中,情况并非如此。在一次操作中读取的字节变化很大。我认为这是有道理的,因为如果在发送消息时服务器端有暂停,客户端不应该等到读取缓冲区被填满。 Read()/EndRead() 是否固有地具有某种超时机制?

我试图找出 Mono 如何在 NetworkStream 中实现 Read() 并进行跟踪,直到调用外部方法 Receive_internal() 为止。

最佳答案

它读取网络流上或缓冲区已满时可用的所有数据。以先到者为准。您已经注意到这种行为。

因此,您需要处理所有字节并查看消息是否完整。您可以通过构建消息来做到这一点。请参阅 .NET question about asynchronous socket operations and message framing 了解如何执行此操作。

至于超时问题,如果假设您问的是 beginread 是否有超时,我会说没有,因为它只是等待数据到达流并将其放入缓冲区,然后您可以处理传入的字节.

读取操作中可用的字节数取决于您的网络(例如延迟、代理节流)和发送数据的客户端等因素。

BeginRead 行为总结:

  • 调用 BeginRead(); -> 等待字节到达流......
  • 1 个字节或更多字节已到达流
  • 开始将第 2 步中的字节放入给定
  • 的缓冲区中
  • 调用 EndRead(); -> 缓冲区内的字节可以被 EndRead() 处理;
  • 最常见的做法是再次重复所有这些步骤。
  • 10-05 19:21