TCP的延遲ACK機制一說到TCP,人們就喜歡開始扯三步握手之類的,那只是其中的一個環節而已。實際上每一個數據包的正確發送都是一個類似握手的過程,可以簡單的把它視為兩步握手。一個發送,一個反饋。但無論發送還是反饋都是有成本的,所以就有了延遲ACK機制。
TCP雖然是傳輸層協議的,但它畢竟是一個高級協議,它的數據傳輸也是基於上一層協議的數據幀的。即使一次發送一個字節的數據,也需要一個幾十字節的IP包頭來裝配,更何況TCP的傳輸是兩步的,是需要反饋確認的,那樣的話效率就非常低。所以就像我們合并HTTP請求一樣,TCP自身也有一種機制來合并一些ACK反饋消息,這就是延遲ACK機制。
當一個數據發送時,發送放一開始並不知道數據是否發送成功,它只能等對方的ACK反饋。當然,在交互過程中一次也不止處理一個數據包,不需要確認前一個包是否已發送就可以發送後面的數據,因為接收方會負責給這些包排序,不用擔心順序問題。而延遲ACK機制就是讓接收方在收到數據後不立即反饋ACK消息,而是等到一小段時間,如果之後還有收到其他包就把這些ACK消息一起放入一個包中反饋給客戶端。
這個延遲ACK機制並不會延遲太長時間,因為發送端對ACK反饋消息的等待是有時限的,這就是TCP對數據傳輸時的超時時間。如果延遲太久可能會導致超時,所以這個延遲ACK的值通常不會超過200ms。
如果我們做一個上傳的程序要顯示進度條,那就需要知道每個包是否都發送成功。而延遲ACK機制就會讓這個成功報告延遲,發送端的統計頻率就會變低。當然,很多高級語言自帶的Socket封裝並沒有提供收到ACK反饋消息時的觸發事件,所以上傳進度條的實現在很多時候是非不容易的。
這個延遲ACK機制還會給計算網絡延遲帶來影響。因為接收端在收到數據時並不立即反饋,這個等待的時間對於發送端來說會被算入網絡延遲中。這就是為什麼有時候即便是局域網的TCP測試也會有很大延遲的原因。
當然,延遲ACK只是TCP的一個機制而已,它並不總被啟用。TCP是很智能的,它會根據傳輸的“經驗”來自動選擇最適用的算法,延遲ACK只是其中的一個選擇而已。
TCP的延遲ACK機制一說到TCP,人們就喜歡開始扯三步握手之類的,那只是其中的一個環節而已。實際上每一個數據包的正確發送都是一個類似握手的過程,可以簡單的把它視為兩步握手。一個發送,一個反饋。但無論發送還是反饋都是有成本的,所以就有了延遲ACK機制。
TCP雖然是傳輸層協議的,但它畢竟是一個高級協議,它的數據傳輸也是基於上一層協議的數據幀的。即使一次發送一個字節的數據,也需要一個幾十字節的IP包頭來裝配,更何況TCP的傳輸是兩步的,是需要反饋確認的,那樣的話效率就非常低。所以就像我們合并HTTP請求一樣,TCP自身也有一種機制來合并一些ACK反饋消息,這就是延遲ACK機制。
當一個數據發送時,發送放一開始並不知道數據是否發送成功,它只能等對方的ACK反饋。當然,在交互過程中一次也不止處理一個數據包,不需要確認前一個包是否已發送就可以發送後面的數據,因為接收方會負責給這些包排序,不用擔心順序問題。而延遲ACK機制就是讓接收方在收到數據後不立即反饋ACK消息,而是等到一小段時間,如果之後還有收到其他包就把這些ACK消息一起放入一個包中反饋給客戶端。
這個延遲ACK機制並不會延遲太長時間,因為發送端對ACK反饋消息的等待是有時限的,這就是TCP對數據傳輸時的超時時間。如果延遲太久可能會導致超時,所以這個延遲ACK的值通常不會超過200ms。
如果我們做一個上傳的程序要顯示進度條,那就需要知道每個包是否都發送成功。而延遲ACK機制就會讓這個成功報告延遲,發送端的統計頻率就會變低。當然,很多高級語言自帶的Socket封裝並沒有提供收到ACK反饋消息時的觸發事件,所以上傳進度條的實現在很多時候是非不容易的。
這個延遲ACK機制還會給計算網絡延遲帶來影響。因為接收端在收到數據時並不立即反饋,這個等待的時間對於發送端來說會被算入網絡延遲中。這就是為什麼有時候即便是局域網的TCP測試也會有很大延遲的原因。
當然,延遲ACK只是TCP的一個機制而已,它並不總被啟用。TCP是很智能的,它會根據傳輸的“經驗”來自動選擇最適用的算法,延遲ACK只是其中的一個選擇而已。