![](/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.