Nagle演算法與CORK演算法區別

來源:互聯網
上載者:User

以下內容轉自:http://blog.163.com/li_xiang1102/blog/static/607140762011111103213616/

1. Nagel演算法

        TCP/IP協議中,無論發送多少資料,總是要在資料前面加上協議頭,同時,對方接收到資料,也需要發送ACK表示確認。為了儘可能的利用網路頻寬,TCP總是希望儘可能的發送足夠大的資料。(一個串連會設定MSS參數,因此,TCP/IP希望每次都能夠以MSS尺寸的資料區塊來發送資料)。Nagle演算法就是為了儘可能發送大塊資料,避免網路中充斥著許多小資料區塊。

        Nagle演算法的基本定義是任意時刻,最多隻能有一個未被確認的小段。 所謂“小段”,指的是小於MSS尺寸的資料區塊,所謂“未被確認”,是指一個資料區塊發送出去後,沒有收到對方發送的ACK確認該資料已收到。

        Nagle演算法的規則(可參考tcp_output.c檔案裡tcp_nagle_check函數注釋):

      (1)如果包長度達到MSS,則允許發送;

      (2)如果該包含有FIN,則允許發送;

      (3)設定了TCP_NODELAY選項,則允許發送;

      (4)未設定TCP_CORK選項時,若所有發出去的小資料包(包長度小於MSS)均被確認,則允許發送;

      (5)上述條件都未滿足,但發生了逾時(一般為200ms),則立即發送。


        Nagle演算法只允許一個未被ACK的包存在於網路,它並不管包的大小,因此它事實上就是一個擴充的停-等協議,只不過它是基於包停-等的,而不是基於位元組停-等的。Nagle演算法完全由TCP協議的ACK機制決定,這會帶來一些問題,比如如果對端ACK回複很快的話,Nagle事實上不會拼接太多的資料包,雖然避免了網路擁塞,網路總體的利用率依然很低。

        Nagle演算法是silly window syndrome(SWS)預防演算法的一個半集。SWS演算法預防發送少量的資料,Nagle演算法是其在發送方的實現,而接收方要做的時不要通告緩衝空間的很小增長,不通知小視窗,除非緩衝區空間有顯著的增長。這裡顯著的增長定義為完全大小的段(MSS)或增長到大於最大視窗的一半。

注意:BSD的實現是允許在空閑連結上發送大的寫操作剩下的最後的小段,也就是說,當超過1個MSS資料發送時,核心先依次發送完n個MSS的資料包,然後再發送尾部的小資料包,其間不再延時等待。(假設網路不阻塞且接收視窗足夠大)


        舉個例子,比如之前的blog中的實驗,一開始client端調用socket的write操作將一個int型資料(稱為A塊)寫入到網路中,由於此時串連是閒置(也就是說還沒有未被確認的小段),因此這個int型資料會被馬上發送到server端,接著,client端又調用write操作寫入‘\r\n’(簡稱B塊),這個時候,A塊的ACK沒有返回,所以可以認為已經存在了一個未被確認的小段,所以B塊沒有立即被發送,一直等待A塊的ACK收到(大概40ms之後),B塊才被發送。整個過程:

          這裡還隱藏了一個問題,就是A塊資料的ACK為什麼40ms之後才收到?這是因為TCP/IP中不僅僅有nagle演算法,還有一個TCP確認延遲機制 。當Server端收到資料之後,它並不會馬上向client端發送ACK,而是會將ACK的發送延遲一段時間(假設為t),它希望在t時間內server端會向client端發送應答資料,這樣ACK就能夠和應答資料一起發送,就像是應答資料捎帶著ACK過去。在我之前的時間中,t大概就是40ms。這就解釋了為什麼'\r\n'(B塊)總是在A塊之後40ms才發出。
        當然,TCP確認延遲40ms並不是一直不變的,TCP串連的延遲確認時間一般初始化為最小值40ms,隨後根據串連的重傳逾時時間(RTO)、上次收到資料包與本次接收資料包的時間間隔等參數進行不斷調整。另外可以通過設定TCP_QUICKACK選項來取消確認延遲。
        關於TCP確認延遲的詳細介紹可參考:http://blog.csdn.net/turkeyzhou/article/details/6764389

2. TCP_NODELAY 選項

        預設情況下,發送資料採用Negale 演算法。這樣雖然提高了網路輸送量,但是即時性卻降低了,在一些互動性很強的應用程式來說是不允許的,使用TCP_NODELAY選項可以禁止Negale 演算法。

        此時,應用程式向核心遞交的每個資料包都會立即發送出去。需要注意的是,雖然禁止了Negale 演算法,但網路的傳輸仍然受到TCP確認延遲機制的影響。

3. TCP_CORK 選項

        所謂的CORK就是塞子的意思,形象地理解就是用CORK將串連塞住,使得資料先不發出去,等到拔去塞子後再發出去。設定該選項後,核心會儘力把小資料包拼接成一個大的資料包(一個MTU)再發送出去,當然若一定時間後(一般為200ms,該值尚待確認),核心仍然沒有組合成一個MTU時也必鬚髮送現有的資料(不可能讓資料一直等待吧)。
        然而,TCP_CORK的實現可能並不像你想象的那麼完美,CORK並不會將串連完全塞住。核心其實並不知道應用程式層到底什麼時候會發送第二批資料用於和第一批資料拼接以達到MTU的大小,因此核心會給出一個時間限制,在該時間內沒有拼接成一個大包(努力接近MTU)的話,核心就會無條件發送。也就是說若應用程式層程式發送小包資料的間隔不夠短時,TCP_CORK就沒有一點作用,反而失去了資料的即時性(每個小包資料都會延時一定時間再發送)。

4. Nagle演算法與CORK演算法區別

  Nagle演算法和CORK演算法非常類似,但是它們的著眼點不一樣,Nagle演算法主要避免網路因為太多的小包(協議頭的比例非常之大)而擁塞,而CORK演算法則是為了提高網路的利用率,使得總體上協議頭佔用的比例儘可能的小。如此看來這二者在避免發送小包上是一致的,在使用者控制的層面上,Nagle演算法完全不受使用者socket的控制,你只能簡單的設定TCP_NODELAY而禁用它,CORK演算法同樣也是通過設定或者清除TCP_CORK使能或者禁用之,然而Nagle演算法關心的是網路擁塞問題,只要所有的ACK回來則發包,而CORK演算法卻可以關心內容,在前後資料包發送間隔很短的前提下(很重要,否則核心會幫你將分散的包發出),即使你是分散發送多個小資料包,你也可以通過使能CORK演算法將這些內容拼接在一個包內,如果此時用Nagle演算法的話,則可能做不到這一點。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.