TCP/IP之(四)Delay ack 和 Nagle算法


Delay ack(延遲確認)

正常情況下服務器收到一個請求時就會立即回覆ACK確認給客戶端,然後客戶端再發送下一個包,服務器再進行回覆。有時候服務器回覆的ACK包有長度,但實際內容長度爲0,這也沒關係屬於正常的。不過一次發送一次確認效率比較低,能不能收多次批量確認一次呢?這就是延遲確認。

Delay ack是說收到包不立即回覆ack,而是等一會兒默認200毫秒,看看這段時間是否有還有包發過來(屬於同一客戶端)如果有就一起發送ACK確認,如果超時了還沒有等到那麼就直接發送這一個確認包。在延遲確認期間ack不是立即發送而是等待200毫秒,如果有就一起發送,或者如果湊夠2個ack包就一起發送;如果在等200毫秒還沒有就發送者一個ACK包。

所以正常情況下抓包都是一個數據包後面緊跟一個ACK確認包。


Nagle算法

如果服務器接收窗口大於MSS並且客戶端要發送的數據大於一個MSS長度(1460)的就立即發送;否則就等待前面發出去包是不是還沒有ACK,如果沒有剩下的小包就等前面的ack返回之後再發送。也就是說包很小,然後又有包發給服務器而且還沒有收到ack,那麼就等等ack返回之後再發送剩下的包。


如果客戶端啓用Nagle並且服務器啓用了delay ack會怎麼樣?

比如客戶端發送一個HTTP請求給服務器,這個請求有1560個字節,握手的MSS是1460個字節。那麼這1560個字節就會分成2個TCP包,第一個1460,第二個100。第一個發送出去後,服務器收到,因爲延遲確認,服務器等待200毫秒,客戶端開啓了Nagle(默認開啓)由於第二個包100字節很小,所有它就等待前一個包的ack返回後再進行發送,這時雙方就進入互相等待的階段,直到200毫秒超時,服務器發送ack,然後客戶端再發送剩餘的一個包。


再說一個例子引用自:http://www.stuartcheshire.org/papers/nagledelayedack/

傳輸數據是99,900字節,速度5.2M每秒;如果傳輸數據是100,000字節速度是2.7M每秒。多了10字節爲什麼速度下降這麼多?

99,900 bytes = 68 全尺寸包 1448字節每個包,另外剩餘1436字節最後一個包
100,000 bytes = 69 全尺寸包 1448字節每個包,另外剩餘88字節最後一個包

說明:一個MSS是1460,爲什麼上面一個包是1448呢?因爲那12個字節,因爲Windows操作系統是1460,蘋果或者其他操作系統多了一個時間戳選項,TCP分段大小就少了所以是1448個字節。上面的例子是按照Linux操作系統來說的。


68個包會立即發發送,因爲68是偶數,所以服務器最後肯定收到2個包,然後發送ACK給客戶端,然後客戶端立即發送剩餘的1436字節,整個過程沒有等待。如果是69個包由於是奇數,服務器最後一次收到是1個包,所以等待200毫秒,然後客戶端由於剩下88個字節也會等待,這樣就增加了整體傳輸時間,超時之後再發送最後一個88個字節。


wKiom1nAd2ixUKNiAADCmJLKP4o553.jpg

上圖是傳輸100,000字節

wKiom1nAd2iBHCZeAAC569fDWNE219.jpg

上圖是傳輸99,900字節


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章