TCP-IP詳解:Delay ACK

參考書籍:TCP/IP詳解,卷1:協議


基本概念

先了解一下,TCP傳輸的數據流的分類:

TCP交互數據流:一般情況下數據總是以小於MSS的分組發送,做的是小流量的數據交互,常見的應用比如SSH,Telnet等

TCP成塊數據流:TCP盡最大能力的運載數據,數據基本都是按照MSS發送,常見的應用有FTP,Iperf等


交互數據

交互式的數據傳輸其實應用於日常生活中比較多一些,比如說聊天,遠程登錄等,我們通過一個實驗來觀察下交互數據流,我這裏使用一個127.0.0.1讓server和client進行通信,server不斷的回顯client發送過去的數據。

1. Client 使用port 57600 連接到 Server 6666  IP 127.0.0.1

2. Client 發送s到Server

3. Server 收到s,並將s回顯給Client

上述的過程明顯是一個交互式的輸入,看下tcpdump的抓包,其中4/5/6/7 四個包是客戶端發送s,然後回顯的過程,簡單的分析下

a. 4號包表示,客戶端發送一個s數據到 服務器

b. 5號包表示,單獨的一個ACK,即告訴客戶端已經收到s了

c. 6號包表示,服務器回顯數據s

d. 7號包表示,客戶端確認已經收到回顯


不難看出,5/6號包可以將確認和數據完全一起發送,這樣可以減少網絡中ACK的小包了,提高這類數據的發送效率。其實這種技術就叫delay ACK


Delay Ack

簡單的說,Delay Ack就是延時發送ACK,在收到數據包的時候,會檢查是否需要發送ACK,如果需要的話,進行快速ACK還是延時ACK,在無法使用快速確認的條件下,就會使用Delay Ack。

TCP在何時發送ACK的時候有如下規定:

1.當有響應數據發送的時候,ACK會隨着數據一塊發送

2.如果沒有響應數據,ACK就會有一個延遲,以等待是否有響應數據一塊發送,但是這個延遲一般在40ms~500ms之間,一般情況下在40ms左右,如果在40ms內有數據發送,那麼ACK會隨着數據一塊發送,對於這個延遲的需要注意一下,這個延遲並不是指的是收到數據到發送ACK的時間延遲,而是內核會啓動一個定時器,每隔200ms就會檢查一次,比如定時器在0ms啓動,200ms到期,180ms的時候data來到,那麼200ms的時候沒有響應數據,ACK仍然會被髮送,這個時候延遲了20ms.

3.如果在等待發送ACK期間,第二個數據又到了,這時候就要立即發送ACK!

優點:減少了數據段的個數,提高了發送效率

缺點:過多的delay會拉長RTT

先通過一組實驗來看下效果: 分別讓服務器在0ms/30ms/40ms/50ms延時的情況下進行回顯,看看數據的交互情況

0ms的狀況:第一個字符沒有Delay ACK的狀況,後面的就一直出現data和ACK一起發送的狀況,也就是說ACK不是立即回覆,然後在定時器到達之前有數據發送和數據一塊發送


30ms的狀況:我們看到第一個字符和0ms的狀況一樣,也是快速回復ACK,之後的字符就是delay ACK,接收到數據不會立馬回覆ACK,等了30ms左右,有數據需要發送!看起來30ms定時器也沒有到期


40ms的狀況:這個就不在有delay ACK的狀況,比較奇怪,可能是kernel有些優化吧,基本都是立即回覆ACK了,感覺像是滿足了快速回復ACK的條件


50ms的狀況:50ms的情況和40ms的情況是一致的。


通過做實驗我們可以得到這樣的一個結論:

1.一般情況下載40ms內基本都會等待data,如果有data就會一塊發送,但是超出了這個時間,都是使用的快速ACK,具體原因目前未知

2.無論多少ms的延時,第一個包都是使用快速ACK,具體原因未知

所以我們這個地方還留有2個疑問,等到後續弄明白再來補充。


關閉Delay ACK

如果需要立即回覆ACK,那麼可以使用TCP_QUICKACK這個選項來啓動快速ACK,先看下Linux關於這個option的描述:

Enable quickack mode if set or disable quickack mode if cleared.  In quickack mode, acks are sent immediately, rather than delayed if needed in  accordance  to  normal  TCP operation.   This  flag  is not permanent, it only enables a switch to or from quickack mode.  Subsequent operation of the TCP protocol will once again enter/leave quickack  mode depending on internal protocol processing and factors such as delayed ack timeouts occurring and data transfer.  This option should not be used in code intended to  be portable.

總結一下要點:

1. 如果在快速的ACK模式下,ACK被立即發送

2. 這個flag並不是永久的,系統會判定是交互數據流,仍然會啓動delay ACK,所以這個flag在recv之後需要重新設置

我們直接看下實驗結果


從結果來看:

每一個字符回顯過程,服務器都是data和ACK分開發送的,收到數據之後第一時間立即回覆ACK包!如果不設置QIUCKACK的話,從30ms實驗的結果來看,就是數據包和ACK一起發送。


參考文檔

1.http://blog.chinaunix.net/uid-28387257-id-3658980.html

2.http://blog.csdn.net/zhangskd/article/details/45116553

3.http://blog.csdn.net/sctq8888/article/details/7398967


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