使用TcpClient读取NetworkStream时设置超时

本文关键字:设置 超时 NetworkStream TcpClient 读取 使用 | 更新日期: 2023-09-27 18:25:04

我实现了TCP客户端以使用TcpClient(C#.NET 4)连接到服务器:

// TCP client & Connection
TcpClient client = new TcpClient();
client.Connect(new IPEndPoint(IPAddress.Parse(IP), PORT));
NetworkStream clientStream = client.GetStream();
// Get message from remote server
byte[] incomingBuffer = new byte[1024];
Int32 bytes = clientStream.Read(incomingBuffer, 0, incomingBuffer.Length);
string problesWithThis = System.Text.Encoding.ASCII.GetString(incomingBuffer, 0, bytes);

与服务器的连接运行良好。但我只能从服务器上读取部分答案,在下次尝试连接时会读取未送达的部分消息

我尝试设置NetworkStream超时:

// No change for me   
clientStream.ReadTimeout = 10000;

然后我试着模拟超时:

// This works well, the client has enough time to read the answers. But it's not the right solution.
// ....
NetworkStream clientStream = client.GetStream();
Thread.Sleep(TimeSpan.FromSeconds(1));
// Read stream ....

使用TcpClient读取NetworkStream时设置超时

数据以数据包的形式通过TCP传输,数据包以串行方式到达(但不一定以正确的顺序)。当数据可用时,即当逻辑上(如果不是按时间顺序)接收到下一个数据包时,clientStream.Read()将立即返回该(以及任何其他o-o-sequence)数据包中的数据,无论这是否是发送方发送的所有数据。

您的Thread.Sleep()会让程序等待一秒钟——在这段时间里,有多个数据包到达并在系统级进行缓冲,因此对clientStream.Read()的调用将立即返回可用数据。

处理此问题的正确方法是循环Read(),直到BytesAvailable()变为零或检测到完整的应用层协议元素。