Nagle演算法是針對網路上存在的微小分組可能會在廣域網上造成擁塞而設計的。該演算法要求一個TCP連接上最多只能有一個未被確認的未完成的小分組,在該分組確認到達之前不能發送其他的小分組。同時,TCP收集這些少量的分組,併在確認到來時以一個分組發出去。它的設計規則如下: (1)如果包長度達到最大報文長度( ...
Nagle演算法是針對網路上存在的微小分組可能會在廣域網上造成擁塞而設計的。該演算法要求一個TCP連接上最多只能有一個未被確認的未完成的小分組,在該分組確認到達之前不能發送其他的小分組。同時,TCP收集這些少量的分組,併在確認到來時以一個分組發出去。它的設計規則如下:
(1)如果包長度達到最大報文長度(MSS,Maximum Segment Size),則允許發送;
(2)如果該包含有FIN,則允許發送;
(3)設置了TCP_NODELAY選項,則允許發送;
(4)未設置TCP_CORK選項時,若所有發出去的小數據包(包長度小於MSS)均被確認,則允許發送;
(5)上述條件都未滿足,但發生了超時(一般為200ms),則立即發送。與Nagle演算法相對應的TCP確認延遲機制(TCP Delayed acknowledge)設計的作用是接收到數據後延遲ACK的發送(40ms),使得TCP協議棧有機會合併多個ACK以提高性能。
由於有Nagle演算法,如果發送端啟用了Nagle演算法,接收端啟用了TCP Delayed Acknowledge。當發送端發起兩次寫一次讀的時候,第一次寫,由於TCP沒有等待ACK,直接發出去了,而第二次寫的時候,第一次寫的ACK還沒有接收到,從而等待;而接收端有Delayed Acknowledge機制,會等待40ms以提供合併多個ACK的機會。Nagle演算法的使用在一些實時性要求比較高的場合,會引起一些問題。比如項目中設計的UI滑鼠遠程式控制制遠端的機器時,發現遠端的滑鼠操作很卡頓,這是因為滑鼠消息的發送端由於Nagle演算法的預設開啟,是有延遲的,對相應的socket設置為TCP_NODELAY即可關閉Nagle演算法:
setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,(char*)&flag,sizeof(flag));