使用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 ....
数据以数据包的形式通过TCP传输,数据包以串行方式到达(但不一定以正确的顺序)。当数据可用时,即当逻辑上(如果不是按时间顺序)接收到下一个数据包时,clientStream.Read()
将立即返回该(以及任何其他o-o-sequence)数据包中的数据,无论这是否是发送方发送的所有数据。
您的Thread.Sleep()
会让程序等待一秒钟——在这段时间里,有多个数据包到达并在系统级进行缓冲,因此对clientStream.Read()
的调用将立即返回可用数据。
处理此问题的正确方法是循环Read()
,直到BytesAvailable()
变为零或检测到完整的应用层协议元素。