一分鍾理解TCP重傳


為什么需要重傳

任何信息在介質中傳輸可能丟失,這是由於傳輸介質的物理特性決定的,所以網絡不可能被設計為“可靠的”(不是由於考慮“性能”原因而是壓根做不到)。既然物理層無法提供可靠數據傳輸那么只能由協議提供可靠傳輸了,其中最有名的協議就是TCP了。

TCP是基於IP的網絡協議,它提供可靠、有序的數據傳輸。在數據傳輸之前客戶端和服務器端通過三次握手建立連接,建立連接的就是雙方交換Seq(數據包序號)、MSS(每個TCP數據包大小) 、Win(滑動窗口,一次可以確認多少個TCP數據包),連接建立完成后每個TCP數據包都要被ACK(確認)。簡單來說TCP通過確認/重傳機制實現了“數據包可靠傳輸”。

重傳原理

TCP數據包頭部包含了兩個字段——Seq表示數據包序號,ACK表示確認序號。下面演示了三次握手過程中Seq和ACK的變化過程。

640

客戶端隨機取一個值x作為Seq發送到服務器端;服務器端回復一個TCP數據包,頭部包含Seq(隨機值y),ACK=x+1。注意這里有一個常見的誤區,ack確認的是當前數據包的“下一個”數據包,ack其實可以作為“期望得到的下一個seq”。客戶端收到服務器端回復之后單獨回復一個ack=y+1,就完成TCP的握手了。

后續數據包傳遞都會延續seq和ack的值,如果發送端某個數據包丟失了那么接收端不會發送ack(其實是duplicate ack),發送端在等待一段時間后發現沒有ack,於是主動重發數據包。發送端的等待的時間叫RTO(Retransmission TimeOut)。

RTO的選擇很重要,如果太大那么網絡帶寬利用率會特別低,發送端要過很久才知道要重傳而此時要重傳的數據是在太多嚴重浪費帶寬資源。如果太小在高延時的網絡高帶寬(恩,你訪問國外網站就屬於這種網絡)中也會浪費帶寬資源。於是就有了Fast Retransmit機制,簡單來說當發送端發現來自接收端的多個重復ACK(duplicate ack)的時候就不再等待RTO而是直接選擇重發。

總結一下:經典TCP重發是發送端主動重發的,當數據包經歷了一段時間后還沒有被接收端確認此時發送端主動重發數據包。Fast Retransmit是由接收端主動要求重發的,當接收端收到了“不想要”的數據包時會重復ACK“上一個”數據包從而觸發發送端的重發。這兩種重發策略一般是同時使用,它們是互補的。

舉個例子:發送端有D1(1-10)、D2(11-20)、D3(21-30)、D4(31-40)四個數據包要發送,每個數據包10bytes用括號內的數字表示。

  • 亂序的情況:接收端收到D1,發送ack=11(D2的序號)。如果在發送過程中D4在D1之后達由於D4攜帶的seq=31所以接收端會丟棄這個數據包然后再次發送ack=11。此時發送端會收到兩個ack(duplicate ack)如果開啟了Fast Retransmit特性那么發送端立即從D2開始重新發送。
  • 丟包的情況:接收端收到D1,發送ack=11(D2的序號)。如果在發送過程中D2丟失那么后續到達的包是D3,由於D3攜帶的seq=21所以接收端會丟棄這個數據包然后再次發送ack=11。此時發送端也會出現duplicate ack從而觸發重傳。

如果接收端的ACK數據包丟失了或者網絡時延太高那么也會觸發重傳。因為發送端對每個數據包都設置了一個RTO,如果到時間沒有收到ACK它會“主動”重發數據包。

Q&A

Q:多線程對一個Socket寫入是否會觸發TCP重發?程序上是否要考慮“亂序”?

A:首先要搞清楚一點,我們往Socket寫入的數據是“應用層數據包”而不是TCP數據包。TCP/IP協議棧會把應用層數據包划分出多個TCP數據包發送出去,每次write都會生成N個連續的TCP數據包。所以即便我們多線程往Socket寫入也不會出現TCP數據包的亂序(應用層數據包可能是亂序的)。

Q:重傳和擁塞控制有什么關系?

A:TCP擁塞控制是指盡可能的利用帶寬,它圍繞4個核心概念展開:慢啟動、擁塞避免和快速重傳、快速恢復。其中快速重傳、快速恢復屬於TCP重傳機制,慢啟動是指對滑動窗口的控制,擁塞避免好重傳機制有一定關系,如果存在大量重傳那么網絡上可能出現了擁塞(擁塞避免的關鍵是識別擁塞)。

Q:怎么看“替代TCP”的說法?

A:TCP最遭人詬病的就是它的重傳機制不可控。如果網絡延時比較高或者質量比較差有一定丟包(特別是移動網絡),TCP的重傳機制觸發“不及時”這就導致應用體驗很差。比如一個1000幀的視頻丟了第100幀那么后續的900幀都要重傳(即便已經收到了)。當然這只是一個例子,視頻還是可以做一定“彌補”的),如果是手機游戲(比如王者榮耀、荒野行動)情況就沒有這么樂觀了。為了盡可能的讓“重傳”可控於是誕生了各種“替代TCP”的自制協議(大部分是基於UDP),比如Google的QUIC、kcp。我個人對這方面研究不多,總體而言它們犧牲了TCP的一些“通用特性”來換取一定的“靈活性”,所以並不是驚天地泣鬼神的“替代TCP”。

Q:怎么看TCP單邊加速

A:TCP單邊加速是指針對通訊的某一端做性能加速,市面上有很多這種產品。但是個人覺得這些都是騙人的,並沒有一種算法適合所有網絡情況。要根據不同的網絡情況配置不同的擁塞控制算法。比如“國際鏈路”屬於高延時高帶寬,配置了Google的BBR算法“梯子”的速度至少能提高70-80%(你懂得)。

from:https://mp.weixin.qq.com/s?__biz=MzIxMjAzMDA1MQ==&mid=2648945945&idx=1&sn=f92e903929975e05978ba57be64ba2bc&chksm=8f5b5215b82cdb03c3f6f57ff63ee3f24bc1029dd147b7524d44baa36a10be65c24f6067adec#rd


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM