Nagle算法 TCP_NODELAY和TCP_CORK

Nagle算法
根據創建者John Nagle命名。該算法用於對緩衝區內的一定數量的消息進行自動連接。該處理過程(稱爲Nagling),通過減少必鬚髮送的封包的數量,提高了網絡應用 程序系統的效率。Nagle算法,由Ford Aerospace And Communications Corporation Congestion Control in IP/TCP internetworks(IETF RFC 896)(1984)定義,最初是用於緩衝Ford的私有TCP/IP網絡擁塞情況,不過被廣泛傳播開來。

Nagle的文檔定義了一種他稱之爲小封包問題的解決方法。當某個應用程序每次只產生一字節的數據,就會導致網絡由於這樣的小封包而過載(該情況通 常被稱爲“發送端SB窗口併發症”),從而產生該問題。一個源自鍵盤的單一字符-1字節的數據-可能導致一個41字節的封包被傳送,該封包包含了1字節的 有用數據和40字節的頭部數據。這種4000%過載的情況,在像APRANET這樣只有很輕負載的網絡中是可以接受的,但在像Ford這樣的負載很重的網 絡中,可能強制重傳,導致封包丟失,並且通過過度擁擠交換節點和網關降低了傳播速度。更進一步,當連接被丟棄時,吞吐量可能被降低。Nagle算法-通常 的實現方法是在一個TCP程序中插入兩行代碼-在發送方,對標識爲沒有迴應的數據進行緩衝(存儲)(這句怪怪的,其實應該是對未發送數據按順序進行緩衝,在發送時進行拼接)。順序發送的數據將被保持到接收到被標識數據的迴應或者一整包有價值的數據需要被髮送。

雖然Nagle算法用於解決Ford網絡內產生的問題,但同樣的問題也出現在APRANet。通過網絡,Nagling被廣泛實現,包括 internet,並且產生了巨大的效用-雖然某些時候在高交互性環境如一些C/S情況下不希望進行該處理。在這種情況下,可以通過 TCP_NODELAY套接字選項關閉Nagling。

注:Nagle雖然解決了小封包問題,但也導致了較高的不可預測的延遲,同時降低了吞吐量。

實際上這就的你動手來自己實現以下Nagle算法了。實際上Nagle算法並不是很複雜,他的主要職責是數據的累積,實際上有兩個門檻:一個就是緩 衝區中的字節數達到了一定量,另一個就是等待了一定的時間(一般的Nagle算法都是等待200ms);這兩個門檻的任何一個達到都必須發送數據了。一般 情況下,如果數據流量很大,第二個條件是永遠不會起作用的,但當發送小的數據包時,第二個門檻就發揮作用了,防止數據被無限的緩存在緩衝區不是好事情哦。 瞭解了TCP的Nagle算法的原理之後我們可以自己動手來實現一個類似的算法了,在動手之前我們還要記住一個重要的事情,也是我們動手實現Nagle算 法的主要動機就是我想要緊急發送數據的時候就要發送了,所以對於上面的兩個門檻之外還的增加一個門檻就是緊急數據發送。現在可以開始工作了,我們這裏主要 給出思路:

  1. 首先我們必須在SOCKET之上再建立一層,來定義我們的自己的傳輸控制,我們的Nagle算法也是在這層裏面實現的。
  2. Disable哪個TCP的Nagle算法,都自己動手寫了,要它幹嗎
  3. 使 用Select函數來查看是否可以發送數據,當然我們實質是否可寫的fd_set的時候需要加入我們的三個門檻,首先是按照字節和緊急數據來檢查,一般情 況下這兩個條件就搞定了,然後再按照時間來決定。我們可是使用一個累積字節記數器和一個等待時間計時器。累積字節記數器在每次添加數據到我們的控制層的時 候就累加一下,發送完畢的時候減去響應的字節數;而計時器在第一次將數據提交給控制層的時候啓動(可以使用Windows的GetTickcount來得 到當前的時間),然後在每次發送數據完畢的時候重新復位一下。
  4. 實際上這樣就已經實現了Nagle算法,而且不需要經常調用GetTickCount而降低了系統的性能。
TCP_CORK

TCP鏈接的過程中,默認開啓Nagle算法,進行小包發送的優化。優化網絡傳輸,兼顧網絡延時和網絡擁塞。這個時候可以置位TCP_NODELAY關閉 Nagle算法,有數據包的話直接發送保證網絡時效性。在進行大量數據發送的時候可以置位TCP_CORK關閉Nagle算法保證網絡利用性。儘可能的進 行數據的組包,以最大mtu傳輸,如果發送的數據包大小過小則如果在0.6~0.8S範圍內都沒能組裝成一個MTU時,直接發送。如果發送的數據包大小足 夠間隔在0.45內時,每次組裝一個MTU進行發送。如果間隔大於0.4~0.8S則,每過來一個數據包就直接發送。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章