TCP快速重傳爲什麼是三次冗餘ack

轉載自:https://blog.csdn.net/u010202588/article/details/54563648

        先理解ACK的基本工作原理,當發送端發送第N-1個包後,接收端答覆的ACK序列號實際上跟發送端發送下一個包,也就是第N個包的序列號一致。

假設有個主機ISN是5000,發送500字節報文至接收方。一旦報文接收之後,接收端回覆一個ACK號爲5500的TCP ACK報文,基於以下公式:Sequence Number In + Bytes of Data Received = Acknowledgment Number Out。按照上述計算結果,返回發送端的確認編號實際上是接收端希望收到的序列號。

假設報文長度都爲1,則示例如下:

seq是序列號,這是爲了連接以後傳送數據用的,ack是對收到的數據包的確認,值是等待接收的數據包的序列號。
在第一次消息發送中,A隨機選取一個序列號作爲自己的初始序號發送給B;第二次消息B使用ack對A的數據包進行確認,因爲已經收到了序列號爲x的數據包,準備接收序列號爲x+1(1可以修改爲數據包的長度)的包,所以ack=x+1,同時B告訴A自己的初始序列號,就是seq=y;第三條消息A告訴B收到了B的確認消息並準備建立連接,A自己此條消息的序列號是x+1,所以seq=x+1,而ack=y+1是表示A正準備接收B序列號爲y+1的數據包。seq是數據包本身的序列號;ack是期望對方繼續發送的那個數據包的序列號。上述過程如下圖所示。

重複ACK

是指在接收方收到亂序報文時,所發出的一類TCP報文。TCP使用報文頭的序列號和確認號以有效保證數據按照發送的順序接收和重組。當TCP連接建立以後,握手過程中交換的一個最重要的信息是初始序列號(ISN)。一旦連接雙方設定了ISN之後,接下來發送的報文所包含的序列號增加一個數據載荷值。

以A方發送,B方接收報文爲例。觀察其中第N-1個報文到達B方後,B方的答覆。B收到第N-1報文後,就會答覆1個ACK號爲N的ACK報文,此時如果收不到序列號爲N的報文,則會繼續發送第2個ACK號爲N的答覆報文,此爲重複ACK。如果一直收不到對方序列號爲N的報文,則會出現三次冗餘的ACK,則意味着很大可能出現丟包了。

下面看爲何快速重傳是選擇3次ACK?

主要的考慮還是要區分包的丟失是由於鏈路故障還是亂序等其他因素引發。兩次duplicated ACK時很可能是亂序造成的!三次duplicated ACK時很可能是丟包造成的!四次duplicated ACK更更更可能是丟包造成的!但是這樣的響應策略太慢。丟包肯定會造成三次duplicated ACK!綜上是選擇收到三個重複確認時窗口減半效果最好,這是實踐經驗。

在沒有fast retransmit / recovery 算法之前,重傳依靠發送方的retransmit timeout,就是在timeout內如果沒有接收到對方的ACK,默認包丟了,發送方就重傳,包的丟失原因1)包checksum 出錯 2)網絡擁塞 3)網絡斷,包括路由重收斂,但是發送方無法判斷是哪一種情況,於是採用最笨的辦法,就是將自己的發送速率減半,即CWND 減爲1/2,這樣的方法對2是有效的,可以緩解網絡擁塞,3則無所謂,反正網絡斷了,無論發快發慢都會被丟;但對於1來說,丟包是因爲偶爾的出錯引起,一丟包就對半減速不合理。於是有了fast retransmit 算法,基於在反向還可以接收到ACK,可以認爲網絡並沒有斷,否則也接收不到ACK,如果在timeout 時間內沒有接收到> 2 的duplicated ACK,則概率大事件爲亂序,亂序無需重傳,接收方會進行排序工作;而如果接收到三個或三個以上的duplicated ACK,則大概率是丟包,可以邏輯推理,發送方可以接收ACK,則網絡是通的,可能是1、2造成的,先不降速,重傳一次,如果接收到正確的ACK,則一切OK,流速依然(包出錯被丟)。而如果依然接收到duplicated ACK,則認爲是網絡擁塞造成的,此時降速則比較合理。

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