![](/img/trans.png)
[英]TcpClient's NetworkStream reads incomplete data unless Thread.Sleep(1) is called
[英]NetworkStream doesn't always send data unless I Thread.Sleep() before closing the NetworkStream. What am I doing wrong?
我在将很小的数据(日期)发送到在同一台计算机上运行的另一个TcpClient时遇到问题。
在下面的代码中,您将看到它在关闭NetworkStream之前就处于休眠状态。 如果我删除了Sleep
,则会导致间歇性问题,即另一端的数据不会打开。
我在这里做错什么了吗?
using (TcpClient client = new TcpClient())
{
client.Connect(new IPEndPoint(IPAddress.Loopback, _tcpServerPort));
NetworkStream clientStream = client.GetStream();
byte[] buffer = new ASCIIEncoding().GetBytes(theDateObject.ToString("yyyy-MM-dd HH:mm:ss"));
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
System.Threading.Thread.Sleep(1000); // Remove this line and the data may not arrive at the other end
clientStream.Close();
}
其他一些信息:
Sleep
而不会引起问题(可能是速度较慢的计算机?) Close(int timeout)
(而不是睡眠) Close(int timeout)
NetworkStream,但这没有帮助。 在NetworkStream上以超时调用close表示网络流将在X后台在后台保持打开状态,以允许发送剩余数据。 在后台需要特别注意,因为您的代码不会因此而受阻。 因为您将tcpClient封装在using语句中,所以在您关闭调用之后,将直接处理客户端以及内部的NetworkStream。 在这种情况下,睡眠是可行的,因为它允许发送数据并同时阻塞您的方法,以防止其强制处置资源。
较干净的解决方案是在TcpClient上设置活动的LingerState并设置足够长的超时时间。 请参阅: http : //msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.lingerstate.aspx
如果接收队列不为空(未读取的服务器中的接收缓冲区中有数据,则处置Socket(客户端)将发送TCP RST(重置连接)),并且发送缓冲区中的数据将被丢弃即,如果尚未发送丢失,则等待发送缓冲区为空,然后终止tcp连接。
一种解决方法是关闭发送通道:
client.Client.Shutdown(SocketShutdown.Send)
clientStream.Close();
}
在关闭客户端之前(而不是thread.sleep),这种情况下不会重置连接。
而且.Flush()在网络流上不执行任何操作。
参见: http : //cs.baylor.edu/~donahoo/practical/JavaSockets/RecvQClose.pdf
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.