天天看點

(七)深入淺出TCPIP之深入淺出TCPIP之TCP重傳機制

TCP重傳機制

TCP要保證所有的資料包都可以到達,是以,必需要有重傳機制。

注意,接收端給發送端的Ack确認隻會确認最後一個連續的包,比如,發送端發了1,2,3,4,5一共五份資料,接收端收到了1,2,于是回ack 3,然後收到了4(注意此時3沒收到),此時的TCP會怎麼辦?我們要知道,因為正如前面所說的,SeqNum和Ack是以位元組數為機關,是以ack的時候,不能跳着确認,隻能确認最大的連續收到的包,不然,發送端就以為之前的都收到了。

逾時重傳機制

一種是不回ack,死等3,當發送方發現收不到3的ack逾時後,會重傳3。一旦接收方收到3後,會ack 回 4——意味着3和4都收到了。

但是,這種方式會有比較嚴重的問題,那就是因為要死等3,是以會導緻4和5即便已經收到了,而發送方也完全不知道發生了什麼事,因為沒有收到Ack,是以,發送方可能會悲觀地認為也丢了,是以有可能也會導緻4和5的重傳。

對此有兩種選擇:

  • 一種是僅重傳timeout的包。也就是第3份資料。
  • 另一種是重傳timeout後所有的資料,也就是第3,4,5這三份資料。

這兩種方式有好也有不好。第一種會節省帶寬,但是慢,第二種會快一點,但是會浪費帶寬,也可能會有無用功。但總體來說都不好。因為都在等timeout,timeout可能會很長(在下篇會說TCP是怎麼動态地計算出timeout的)

快速重傳機制

于是,TCP引入了一種叫Fast Retransmit 的算法,不以時間驅動,而以資料驅動重傳。也就是說,如果,包沒有連續到達,就ack最後那個可能被丢了的包,如果發送方連續收到3次相同的ack,就重傳。Fast Retransmit的好處是不用等timeout了再重傳。

比如:如果發送方發出了1,2,3,4,5份資料,第一份先到送了,于是就ack回2,結果2因為某些原因沒收到,3到達了,于是還是ack回2,後面的4和5都到了,但是還是ack回2,因為2還是沒有收到,于是發送端收到了三個ack=2的确認,知道了2還沒有到,于是就馬上重轉2。然後,接收端收到了2,此時因為3,4,5都收到了,于是ack回6。示意圖如下: