2012-02-05 30 views
3

我在想自己是否寫一個完整的消息給NetworkStream會比在多個Write調用中寫入消息的每個部分要好。例如,將在全像這樣寫的消息...向NetworkStream寫一個完整的消息,還是寫每條消息的一部分是一個好主意?

NetworkStream ns = tcpClient.GetStream(); 

    byte[] message = Encoding.ASCII.GetBytes("This is a message."); 
    ns.Write(message, 0, message.Length); 

...比寫這樣一個更好的主意......

NetworkStream ns = tcpClient.GetStream(); 

    byte[] message1 = Encoding.ASCII.GetBytes("This "); 
    byte[] message2 = Encoding.ASCII.GetBytes("is "); 
    byte[] message3 = Encoding.ASCII.GetBytes("a "); 
    byte[] message4 = Encoding.ASCII.GetBytes("message."); 

    ns.Write(message1, 0, message1.Length); 
    ns.Write(message2, 0, message2.Length); 
    ns.Write(message3, 0, message3.Length); 
    ns.Write(message4, 0, message4.Length); 

是否有程序的性能也太大區別或每個方法的網絡性能?

回答

3

就網絡而言,它將是一樣的。但是在客戶端上,如果使用第二種方法,則不需要將全部消息加載到內存中。這在處理大量數據時很有用。例如,讓我們假設你想發送大文件。您可以以塊的形式讀取這些文件,這樣您就不需要將整個文件內容加載到內存中,並將其以塊的形式發送到網絡。客戶端一次只能在內存中加載一個塊。

但顯然如果你已經在內存中的整個消息不打擾,並寫在網絡套接字一次性。

+1

它是否會一樣取決於有點老鷹... – 2012-02-05 17:56:23

4

這會變得棘手,並取決於如何配置套接字。你寫不不直接映射到收到什麼:

  • 網卡可能有它在傳輸分成分組
  • /NIC可以配置爲結合數據包tramsmission插座(減少實際的網絡數據包,但使其難以確保你發送你認爲你已經 - 它可以進行本地緩存)

請特別注意,NetworkStream.Flush()不會做任何事情,這樣你就可以用它來推動任何最後幾個字節

一個很好的折中辦法是包裹NetworkStreamBufferedStream,並配置SocketNoDelay = true(禁用本地輸出緩衝)。 BufferedStream允許您繼續以任意大小的塊(包括單個字節)進行寫入,而不會導致巨大的數據包碎片; BufferedStream將在接近設定大小時自行刷新。然而,重要的是,您現在可以訪問BufferedStreamFlush()方法,其中將緩衝的數據清空到網絡;如果進行復雜的後臺對話並且需要知道您發送了消息的結尾,這會很有用。

否則的風險是客戶端永遠等待響應(沒有意識到它仍然有3個字節緩衝在本地,所以沒有發送完整的請求),並且服務器不響應,因爲它仍在等待請求的最後3個字節。僵局。

相關問題