TCP IP 重傳機制

2021-10-20 01:25:50 字數 3646 閱讀 3266

tcp 實現可靠傳輸的方式之一,是通過序列號與確認應答。

在 tcp 中,當傳送端的資料到達接收主機時,接收端主機會返回乙個確認應答訊息,表示已收到訊息。

但在錯綜複雜的網路,並不一定能如上圖那麼順利能正常的資料傳輸,萬一資料在傳輸過程中丟失了呢?

所以 tcp 針對資料報丟失的情況,會用重傳機制解決。

接下來說說常見的重傳機制:

重傳機制的其中乙個方式,就是在傳送資料時,設定乙個定時器,當超過指定的時間後,沒有收到對方的ack確認應答報文,就會重發該資料,也就是我們常說的超時重傳

tcp 會在以下兩種情況發生超時重傳:

超時時間應該設定為多少呢?

我們先來了解一下什麼是rtt(round-trip time 往返時延),從下圖我們就可以知道:

rtt就是資料從網路一端傳送到另一端所需的時間,也就是包的往返時間。

超時重傳時間是以rto(retransmission timeout 超時重傳時間)表示。

假設在重傳的情況下,超時時間rto「較長或較短」時,會發生什麼事情呢?

上圖中有兩種超時時間不同的情況:

精確的測量超時時間rto的值是非常重要的,這可讓我們的重傳機制更高效。

根據上述的兩種情況,我們可以得知,超時重傳時間 rto 的值應該略大於報文往返 rtt 的值

至此,可能大家覺得超時重傳時間rto的值計算,也不是很複雜嘛。

好像就是在傳送端發包時記下t0,然後接收端再把這個ack回來時再記乙個t1,於是rtt = t1 – t0。沒那麼簡單,這只是乙個取樣,不能代表普遍情況

實際上「報文往返 rtt 的值」是經常變化的,因為我們的網路也是時常變化的。也就因為「報文往返 rtt 的值」 是經常波動變化的,所以「超時重傳時間 rto 的值」應該是乙個動態變化的值

我們來看看 linux 是如何計算rto的呢?

估計往返時間,通常需要取樣以下兩個:

rfc6289 建議使用以下的公式計算 rto:

其中srtt是計算平滑的rtt ,devrtr是計算平滑的rtt 與 最新 rtt 的差距。

在 linux 下,α = 0.125,β = 0.25, μ = 1,∂ = 4。別問怎麼來的,問就是大量實驗中調出來的。

如果超時重發的資料,再次超時的時候,又需要重傳的時候,tcp 的策略是超時間隔加倍。

也就是每當遇到一次超時重傳的時候,都會將下一次超時時間間隔設為先前值的兩倍。兩次超時,就說明網路環境差,不宜頻繁反**送。

超時觸發重傳存在的問題是,超時週期可能相對較長。那是不是可以有更快的方式呢?

於是就可以用「快速重傳」機制來解決超時重發的時間等待。

tcp 還有另外一種快速重傳(fast retransmit)機制,它不以時間為驅動,而是以資料驅動重傳

快速重傳機制,是如何工作的呢?其實很簡單,一圖勝千言。

在上圖,傳送方發出了 1,2,3,4,5 份資料:

所以,快速重傳的工作方式是當收到三個相同的 ack 報文時,會在定時器過期之前,重傳丟失的報文段。

快速重傳機制只解決了乙個問題,就是超時時間的問題,但是它依然面臨著另外乙個問題。就是重傳的時候,是重傳之前的乙個,還是重傳所有的問題。

比如對於上面的例子,是重傳 seq2 呢?還是重傳 seq2、seq3、seq4、seq5 呢?因為傳送端並不清楚這連續的三個 ack 2 是誰傳回來的。

根據 tcp 不同的實現,以上兩種情況都是有可能的。可見,這是一把雙刃劍。

為了解決不知道該重傳哪些 tcp 報文,於是就有sack方法。

還有一種實現重傳機制的方式叫:sack( selective acknowledgment 選擇性確認)。

這種方式需要在 tcp 頭部「選項」字段裡加乙個sack的東西,它可以將快取的地圖傳送給傳送方,這樣傳送方就可以知道哪些資料收到了,哪些資料沒收到,知道了這些資訊,就可以只重傳丟失的資料

如下圖,傳送方收到了三次同樣的 ack 確認報文,於是就會觸發快速重發機制,通過sack資訊發現只有200~299這段資料丟失,則重發時,就只選擇了這個 tcp 段進行重複。

如果要支援sack,必須雙方都要支援。在 linux 下,可以通過net.ipv4.tcp_sack引數開啟這個功能(linux 2.4 後預設開啟)。

duplicate sack 又稱d-sack,其主要使用了 sack 來告訴「傳送方」有哪些資料被重複接收了。

下面舉例兩個栗子,來說明d-sack的作用。

栗子一號:ack 丟包

栗子二號:網路延時

可見,d-sack有這麼幾個好處:

可以讓「傳送方」知道,是發出去的包丟了,還是接收方回應的 ack 包丟了;

可以知道是不是「傳送方」的資料報被網路延遲了;

可以知道網路中是不是把「傳送方」的資料報給複製了;

在 linux 下可以通過net.ipv4.tcp_dsack引數開啟/關閉這個功能(linux 2.4 後預設開啟)。

TCP IP 重傳演算法

重傳定時器 tcp 必須維護乙個重傳定時器,以進行超時重傳 問題 如何設定超時時間間隔 rto?時間間隔太短則可能導致大量不必要的重傳 太長則導致效能下降 tcp 採用了乙個高度動態的演算法,來不斷的調整時間間隔,這個演算法就是 jacobson 1988 演算法 在此演算法中,tcp 需要維護幾個...

TCP重傳機制

tcp進行傳輸時,發出去的請求包在規定時間內沒有收到ack,不管是請求包丟失,還是ack包丟失,還是網路延遲,總之,這裡都是需要有個重傳機制的。常見的導致重傳情況有 資料報傳輸途中丟失 接收端的ack確認報文在傳輸途中丟失 接收端異常未響應ack或被接收端丟棄。tcp的重傳機制有兩種 超時重傳和快速...

TCP IP學習筆記 超時重傳

當網路中出現擁塞,client端在給定的時間收不到server端傳送的ack資訊,那麼client就會認為是包丟失了。此時client就需要重新傳輸包,從包丟失到包重傳這個時間間隔就是rto。為了解決上面的問題,提出了慢啟動演算法和擁塞避免演算法,具體過程如下 當我們傳送的資料報出現亂序時,這個時候...