簡體   English   中英

TcpClient的NetworkStream讀取不完整的數據,除非調用Thread.Sleep(1)

[英]TcpClient's NetworkStream reads incomplete data unless Thread.Sleep(1) is called

我有一種方法,該方法通過TcpClientNetworkStream讀取一些數據,它給了我一些錯誤。

在調查過程中,我發現它實際上可以正常工作……但前提是我使用斷點在Visual Studio 2012的調試器中逐步完成了代碼。

這是我的代碼:

public static byte[] DownloadStream(string hostname, int port, 
    byte[] requestBytes, int bufferSize = 4096)
{
    byte[] responseBytes = null;

    var client = new System.Net.Sockets.TcpClient(hostname, port);

    if (client.Connected)
    {
        using (var stream = client.GetStream())
        {
            stream.Write(requestBytes, 0, requestBytes.Length);
            stream.Flush();

            if (stream.CanRead)
            {
                var responseStream = new System.IO.MemoryStream();

                byte[] buffer = new byte[bufferSize];
                int bytesRead = 0;

                do
                {
                    bytesRead = stream.Read(buffer, 0, buffer.Length);

                    responseStream.Write(buffer, 0, bytesRead);
                }
                while (stream.DataAvailable);

                responseBytes = responseStream.ToArray();
            }
        }
    }

    client.Close();

    return responseBytes;
}

這是非常令人沮喪的,因為沒有真正的錯誤。 顯然,它只需要調試器在讀取NetworkStream時握住它的手即可。

有人知道為什么會這樣嗎? 我該如何解決?


編輯:

由於某些原因,進行此更改可以消除此問題:

                do
                {
                    bytesRead = stream.Read(buffer, 0, buffer.Length);

                    responseStream.Write(buffer, 0, bytesRead);

                     System.Threading.Thread.Sleep(1); //added this line
                }
                while (stream.DataAvailable);

有什么見解嗎?

NetworkStream.DataAvailable屬性不是檢測響應結束的可靠方法。 如果將響應拆分為多個TCP數據包,並且在您檢查DataAvailable尚未發送數據包,則該屬性將返回false,從而提前終止循環。

顯然,您的網絡連接速度足夠快,以便Thread.Sleep(1)為每個后續數據包到達提供足夠的時間。 但是,在連接速度較慢的情況下,這可能不夠用。

為了進行可靠的通信,客戶端和服務器需要就發出信號通知響應結束的方式達成共識。 例如:

  • 服務器可以在實際響應之前將響應的長度作為前綴發送。 客戶端讀取該長度,然后從流中讀取,直到接收到該字節數為止。
  • 服務器可以在實際響應后發送一個特殊的終止符作為后綴。 客戶端從流中讀取,直到遇到終止符為止。 (顯然,終止符不能出現在響應本身的任何位置。)
  • 發送完整個響應后,服務器可以關閉連接。 客戶端從流中讀取,直到關閉連接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM