我在向同一台计算机上运行的另一台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)
关闭NetworkStream(而不是睡觉),但这没有帮助。答案 0 :(得分:1)
在NetworkStream上以超时方式调用close意味着网络流将在后台保持打开X时间以允许发送剩余数据。在后台非常重要,因为您的代码未被此阻止。因为您将tcpClient封装在using语句中,所以客户端和NetworkStream内部将在您关闭调用后直接处理。在这种情况下睡眠是有效的,因为它允许发送数据并在此期间阻止您的方法,以防止它强行处理其资源。
更干净的解决方案是在TcpClient上设置一个具有足够长超时的活动LingerState。请参阅:http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.lingerstate.aspx
答案 1 :(得分:0)
如果您的接收队列不为空(您从尚未读取的服务器获取接收缓冲区中的数据,则配置Socket(客户端)发送TCP RST(重置连接))和发送中的数据丢弃缓冲区,即如果尚未丢失,则等待发送缓冲区为空,然后终止tcp连接。
一种解决方法是关闭发送渠道:
client.Client.Shutdown(SocketShutdown.Send)
clientStream.Close();
}
在关闭客户端(而不是thread.sleep)之前,在这种情况下,连接不会被重置。
.Flush()也不对网络流做任何事情。
请参阅:http://cs.baylor.edu/~donahoo/practical/JavaSockets/RecvQClose.pdf