简体   繁体   English

使用TcpClient读取NetworkStream时设置超时

[英]Set timeout when reading NetworkStream with TcpClient

I implemented TCP client to connect to the server using TcpClient ( C# .NET 4 ): 我实现了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);

Connection to server works well. 与服务器的连接运行良好。 But I can read only part of the answer from the server and undelivered part of the message is read at the next connection attempt . 但是我只能从服务器读取部分答案,而在下一次连接尝试时将读取消息的未传递部分

I tried to set NetworkStream timeout: 我试图设置NetworkStream超时:

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

Then I tried to simulate timeout: 然后我尝试模拟超时:

// 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 ....

Data is transported over TCP in packets, which arrive serially (but not necessarily in the correct sequence). 数据通过TCP以分组形式传输,该分组以串行方式到达(但不一定以正确的顺序到达)。 Immediately when data is available, ie when the logically (if not chronolgically) next packet is received, clientStream.Read() will return with the data in this (and maybe any other oo-sequence) packet(s) - no matter if this is all data the sending side has sent or not. 当有数据可用时,即在逻辑上(如果不是按时间顺序)接收到下一个数据包时, clientStream.Read()将立即与该(可能还有其他oo序列)数据包一起返回数据-不管是否发送方是否已发送所有数据。

Your Thread.Sleep() makes the program wait for a second - in this time more than one packets arrive and are buffered on the system level, so the call to clientStream.Read() will return immediately with the available data. 您的Thread.Sleep()使程序等待一秒钟-此时,一个以上的数据包到达并在系统级别进行缓冲,因此对clientStream.Read()的调用将立即返回可用数据。

The correct way to handle this is to loop your Read() until BytesAvailable() becomes zero or a complete application-layer protocol element is detected. 处理此问题的正确方法是循环Read()直到BytesAvailable()变为零或检测到完整的应用程序层协议元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM