TCP_NODELAY 與演算法

TCP_NODELAY 與演算法

4 人贊了文章

nagle演算法,nagle解決的問題是small-packet problem,原因是比如tenet這種應用,你每次輸入一個byte, 然後你喝口水,再輸入一個byte,你說網路什麼時候發給server呀,你每次輸入一個byte就發送,為了發送一個byte,包裝40Bytes報文頭

好在tcp是流協議,根本沒有什麼報文邊界的概念,所以其實rfc 896解決的問題就是小報文也要帶一個40bytes頭的問題,因為tcp沒有報文邊界,所以我何不等一會,等你蓄積多一點數據,我再一票發出去,比如我蓄積到了超過mss, 或者所以ack都收到了,這時候也到了nagle 的觸發條件,我一個40Bytes的頭帶著緩衝區的數據,比如我這時候有500B, 我總長540Byte就發出去了。假設你極端情況發500次,這時候沒有nagle你要通過網路穿2萬多個位元組。所以nagle本身是一個降低小包報文頭的數量的策略。

nagle偽碼是這樣的

#如果有數據需要發送1. if there is new data to send 2. #分節小於窗口,並且要發發送的數據比一個分節大3. if the window size >= MSS and available data is >= MSS 4. #立刻發送整個分節5. send complete MSS segment now 6. else7. #如果信道里有未確認的數據 8. if there is unconfirmed data still in the pipe9. #暫緩發送,把數據丟進緩衝區排隊,直到收到一個回復, 10. enqueue data in the buffer until an acknowledge is received 11. else12 #如果沒有未收到的ack,立刻發出去。13. send data immediately 14. end if15. end if16. end if

nagle的副作用顯而易見吧。如果你發的message都大於mss,nagle設計的初衷完全廢掉,其實也還好。如果你發送的數據比如mss是1500,你緩衝區還有1000byte出去,而且當你網路慢,重點看上面代碼6-10行,你信道里有沒有收到ack是正常現象在網路跳數多時或者中心交換機擁塞時。所以你這時候就等下一個ack呀。同時蓄積你緩衝區的數據,只要不超過最大發送窗口就OK。關鍵如果你一些應用對網路延時容忍低,這時候就完蛋了,因為你的代碼一直卡到上面代碼6到10行。你這時候也沒有再多的數據發了,那隻好等收回所有ack了。

而TCP_NODELAY這個選項就是繞過nagle,直接發出去,你應該知道什麼時候需要關掉nagle了吧。上面偽碼直接維基拷貝的。

推薦閱讀:

TCP四次分手是在幹什麼?
tcp協議可靠嗎? 怎麼知道自己發出的消息已經被是否被成功接收?
tcp協議握手為什要各隨機一個數字並加一?
怎樣生動描述 TCP 的「三次握手」?

TAG:TCP | 網路協議 | HTTP |