TCP Retransmission的理解

TCP  Retransmission:TCP重傳,因爲網絡數據包未被ACK確認,爲避免數據丟失而進行錯誤恢復,出現重傳的原因很多:

服務器性能下降、網絡數據擁塞、網絡不穩定抖動、程序bug、網絡設備故障等都有可能導致數據重傳。

下面模擬下TCP重傳的現象:

寫一個測試用的服務器和客戶端Socket連接:

客戶端發送代碼如下:

for (int i = 0; i < 5; i++)
                {
                    client.SendAsync(string.Format("!#{0}$!", (i + 1).ToString() + ":>Hello"));
                    Thread.Sleep(200);
                }

 服務器端爲一個帶起始和結束符的格式解析。開啓Wireshark抓包,包過濾的條件參考如下:

((ip.dst==192.168.11.151 and ip.src==192.168.11.140) or (ip.dst==192.168.11.140 and ip.src==192.168.11.151)) and tcp and tcp.port==8500

當點擊發送後,拔掉網線等待1到2秒後插回;觀察抓取到的數據包:

可以看到15:04:13時,出現了一次TCP Retransmission: !#3:>Hello$!!#4:>Hello$!!#5:>Hello$!

接着:TCP Acked unseen segment: unseen是未找到,意思是數據包ACK的消息未被Wireshark抓取到。但未被抓取到並不代表數據未被髮送:

查看服務器端接收區:說明數據被正確的重傳接收了。

 

下文爲重傳的機制介紹:引用網絡:原文出處:http://www.myexception.cn/h/545728.html

引:

TCP Retransmission的機制:當發送方送出一個TCP片段後,將開始計時,等待該TCP片段的ACK回覆。如果接收方正確接收到符合次序的片段,接收方會利用ACK片段回覆發送方。發送方得到ACK回覆後,繼續移動窗口,發送接下來的TCP片段。如果直到計時完成,發送方還是沒有收到ACK回覆,那麼發送方推斷之前發送的TCP片段丟失,因此重新發送之前的TCP片段。這個計時等待的時間叫做重新發送超時時間(RTO, retransmission timeout)。

發送方應該在等待多長時間之後重新發送呢?這是重新發送的核心問題。上述過程實際上有往返兩個方向:1. 發送片段從發送方到接收方的傳輸,2. ACK片段從接收方到發送方的傳輸。整個過程實際耗費的時間稱做往返時間(RTT, round trip time)。如果RTT是固定的,比如1秒,那麼我們可以讓RTO等於RTT。但實際上,RTT的上下浮動很大。比如某個時刻,網絡中有許多交通,那麼RTT就增加。在RTT浮動的情況下,如果我們設置了過小的RTO,那麼TCP會等待很短的時間之後重新發送,而實際上之前發送的片段並沒有丟失,只是傳輸速度比較慢而已,這樣,網絡中就被重複注入TCP片段,從而浪費網絡傳輸資源。另一方面,如果RTO時間過長,那麼當TCP片段已經實際丟失的情況下,發送方不能及時重新發送,會造成網絡資源的閒置。所以,RTO必須符合當前網絡的使用狀況。網絡狀況越好,RTO應該越短;網絡狀況越差,RTO應該越長。

TCP協議通過統計RTT,來決定合理的RTO。發送方可以測量每一次TCP傳輸的RTT (從發送出數據片段開始,到接收到ACK片段爲止),這樣的每次測量得到的往返時間,叫做採樣RTT(srtt, sampling round trip time)。建立連接之後,每次的srtt作爲採樣樣本,計算平均值(mean)和標準差(standard deviation),並讓RTO等於srtt平均值加上四倍的srtt標準差。

RTO = mean + 4 std

(上述算法有多個變種,根據平臺不同有所變化)

平均值反映了平均意義上的RTT,平均往返時間越大,RTO越大。另一方面,標準差越大也會影響RTO。標準差代表了RTT樣本的離散程度。如果RTT上下劇烈浮動,標準差比較大。RTT浮動大,說明當前網絡狀況相對不穩定。因此要設置更長的RTO,以應對不穩定的網絡狀況。

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