gpt4 book ai didi

c# - TcpClient 的 NetworkStream 什么时候完成一次读操作?

转载 作者:可可西里 更新时间:2023-11-01 02:32:53 25 4
gpt4 key购买 nike

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

根据 MSDN 文档,

This method reads data into the buffer parameter and returns the number of bytes successfully read. If no data is available for reading, the Read method returns 0. The Read operation reads as much data as is available, up to the number of bytes specified by the size parameter. If the remote host shuts down the connection, and all available data has been received, the Read method completes immediately and return zero bytes.

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

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

最佳答案

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

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

关于超时问题,假设你问一个beginread是否有超时,我会说没有,因为它只是在等待数据到达流并放入缓冲区,之后你可以处理传入的字节。

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

BeginRead 行为总结:

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

关于c# - TcpClient 的 NetworkStream 什么时候完成一次读操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21792461/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com