2011-03-27 41 views
1

我有一臺服務器通過NetworkStream.Read來管理兩個客戶端。從網絡流中讀取數據包碎片

應用協議是:

ClientMessage [128個字節]→從服務器[128個字節]響應

現在,在服務器端:是否可能,即MyTcpClient.GetStream().Read()只返回< 128字節,雖然所有消息來自客戶端的長度恰好是128字節?

我想這樣一個客戶端消息足夠短,以適應tcp/ip層上的一個數據包 - 但可能會有某種碎片或隨機的,雖然?

NetworkStream.DataAvailable對此有何防範的正確屬性?

運行平穩幾個小時後,我有時會得到奇怪的錯誤和連接損失,指向類似的東西。

在此先感謝。

回答

1

是否有可能,這MyTcpClient.GetStream()。read()返回只< 128字節

是的。您不能假設您對Read()的調用將返回128個字節。

看到docs:讀入 緩衝

的字節總數。這可能小於 請求的字節數,如果很多 字節當前不可用,或者 零(0)如果流的末尾已達到 。

請參閱有關如何正確地從流

this鏈路嘗試是這樣的,而不是:(傳遞一個128長度的字節數組)

private static void ReadWholeArray (Stream stream, byte[] data) 
    { 
     int offset=0; 
     int remaining = data.Length; 
     while (remaining > 0) 
     { 
      int read = stream.Read(data, offset, remaining); 
      if (read <= 0) 
       throw new EndOfStreamException 
        (String.Format("End of stream reached with {0} bytes left to read", remaining)); 
      remaining -= read; 
      offset += read; 
     } 
    } 
1

簡短的回答:

沒有絕對的保證,您將收到整個數據包在一個Read通話,即使包在一個Write電話發送的,它比網絡更小的MTU,即使您實際上正在從回送接口發送/讀取。你無法對此行爲做任何事情。

Read的文件中明確指出:

的實現可自由地返回 較少的字節比如果流的 結束一直沒有 達到甚至要求。

可以做會去什麼像這樣(僞)

While (true) { 
    Read from stream 
    If bytes read == 0 { 
     Socket was closed (buffer should be empty here) 
     Break 
    } 
    Append read data to persistent buffer 
    While (buffer.Length >= 128) { 
     Extract first 128 bytes from buffer (buffer length now reduced by 128) 
     Process message 
    } 
} 
+0

@Job,我怎樣才能處理一個uncomplete信息 ? – 2014-03-06 23:27:45