2010-03-02 62 views
4

我對使用Ubuntu下的Berkeley套接字有疑問。在性能和可靠性方面哪個選項最好?發送大量短信但發送短信或發送少量信息,但發送大量信息?我不知道我應該在這裏遵循哪個主要設計規則。套接字:大消息性能

謝謝大家!

+2

您使用的是SOCK_STREAM還是SOCK_DGRAM套接字? – msw 2010-03-02 15:36:19

+1

由於TCP是一個流,消息大小由協議確定,而不是您的應用程序。流 - 整體 - 沒有大小。 – 2010-03-02 15:54:17

+0

我正在使用TCP。 – Julen 2010-03-03 12:01:33

回答

0

每個網絡消息都有一個40字節長度的標題,但大消息很難路由並且更容易丟失。如果您在談論UDP,那麼最好的消息大小是以太網塊,如果yiu使用TCP,那麼它的長度是1496字節,將它留給網絡層來處理髮送的數量。

1

就可靠性而言,除非您有非常具體的要求,否則不值得擔心。如果你談論的是TCP,它會比管理事情做得更好,直到遇到一些確實需要你擺弄一些旋鈕的邊緣案例,在這種情況下,會有一個更具體的問題。在數據包大小方面,除非你規避Nagel's algorithm,否則你並不真正擁有你可能想到的控制。

對於UDP,可以說最好的做法是使用path MTU discovery,TCP自動爲你做,但作爲一般規則,你可以使用500字節範圍內的東西。如果你開始變得太花哨,你會發現自己重新發明了TCP的一部分。

0

表現你可以用iperf找到自己。運行一些實驗,你會自己看到它。至於可靠性,據我瞭解,如果你使用TCP TCP連接保證數據將被傳遞,當然如果連接沒有中斷。

1

對於TCP,一個選項是使用TCP_CORK套接字選項。請參閱getsockopt手冊頁。在套接字上設置TCP_CORK,寫入一批小消息,然後刪除TCP_CORK選項,它們將以最少數量的網絡數據包進行傳輸。這可以增加吞吐量,但會增加延遲。

+0

看起來像這是僅限於Linux(這可能不是問題)。 – 2010-03-02 16:30:17

0

「在性能和可靠性的選項而言是最好的」

在有損層,性能和可靠性幾乎是一條直線權衡彼此,和更大的專家比我們已經把多年的工作進入尋找甜蜜點,以及擊敗直接交易並同時改善的技術。

您有兩個基本選項:

1)使用流套接字(TCP)。應用程序知道的任何「消息」都是在應用程序層而不是在套接字上定義的。例如,您可能會認爲HTTP請求是一條消息,而響應是另一個方向相反的方向。您應該看到您的工作是儘可能保持輸出緩衝區儘可能完整,並且輸入緩衝區始終爲空。可靠性幾乎與消息長度無關,對於固定大小的數據性能,主要取決於執行的請求響應往返次數,而不是套接字上單個寫入的次數。很明顯,如果你一次發送一個字節的TCP_NODELAY,那麼你會失去性能,但這是非常極端的。

2)使用數據報(UDP)。 「消息」是套接字層實體。性能可能比TCP更好,但是您必須爲可靠性創建自己的系統,並且可能會通過要求重新發送數據來影響性能。 TCP具有相同的問題,但思路更加敏銳等。數據報長度與性能和可靠性之間的交互非常笨拙,因此Duck提到了MTU發現。如果你發送一個大包並且它被分割了,那麼如果有任何一個片段誤入歧途,那麼你的消息就不會到達。有一個N的大小,如果你發送N大小的數據報,它們不會被分割,但是如果你發送N + 1大小的數據報,它們就會發送。因此,+1使失敗消息的數量增加一倍。你不知道N,直到你知道網絡路線(甚至可能還沒有)。因此,在編譯時基本不可能說什麼尺寸會帶來很好的性能:即使你測量它,對於不同的用戶也會有所不同。如果你想優化,沒有別的選擇知道你的東西。

如果您需要可靠性,TCP內置於UDP,UDP也比TCP更有效。潛在的UDP有很大的回報,但應該被認爲是套接字的彙編編程。

還有(3):使用協議來提高UDP可靠性,如RUDP。這不是伯克利風格套接字API的一部分,所以你需要一個庫來提供幫助。