TCP的超時重傳機制與擁塞避免

TCP超時與重傳機制
  
  TCP協議是一種面向連接的可靠的傳輸層協議,它保證了數據的可靠傳輸,對於一些出錯,超時丟包等問題TCP設計的超時與重傳機制。其基本原理:在發送一個數據之後,就開啓一個定時器,若是在這個時間內沒有收到發送數據的ACK確認報文,則對該報文進行重傳,在達到一定次數還沒有成功時放棄併發送一個復位信號。
  這裏比較重要的是重傳超時時間,怎樣設置這個定時器的時間(RTO),從而保證對網絡資源最小的浪費。因爲若RTO太小,可能有些報文只是遇到擁堵或網絡不好延遲較大而已,這樣就會造成不必要的重傳。太大的話,使發送端需要等待過長的時間才能發現數據丟失,影響網絡傳輸效率。
  由於不同的網絡情況不一樣,不可能設置一樣的RTO,實際中RTO是根據網絡中的RTT(傳輸往返時間)來自適應調整的。具體關係參考相關算法。
  通過圖來了解重傳機制:
 這裏寫圖片描述

從圖可以知道,發送方連續發送3個數據包,其中第二個丟失,沒有被接收到,因此不會返回對應的ACK,沒發送一個數據包,就啓動一個定時器,當第二個包的定時器溢出了還沒有收到ack,這時就進行重傳。

TCP慢啓動

  慢啓動是TCP的一個擁塞控制機制,慢啓動算法的基本思想是當TCP開始在一個網絡中傳輸數據或發現數據丟失並開始重發時,首先慢慢的對網路實際容量進行試探,避免由於發送了過量的數據而導致阻塞。
  慢啓動爲發送方的TCP增加了另一個窗口:擁塞窗口(congestion window),記爲cwnd。當與另一個網絡的主機建立TCP連接時,擁塞窗口被初始化爲 1個報文段(即另一端通告的報文段大小)。每收到一個ACK,擁塞窗口就增加一個報文段(cwnd以字節爲單位,但是慢啓動以報文段大小爲單位進行增加)。發送方取擁塞窗口與通告窗口中的最小值作爲發送上限。擁塞窗口是發送方使用的流量控制,而通告窗口則是接收方使用的流量控制。發送方開始時發送一個報文段,然後等待 ACK。當收到該ACK時,擁塞窗口從1增加爲2,即可以發送兩個報文段。當收到這兩個報文段的 A C K時,擁塞窗口就增加爲4。這是一種指數增加的關係。

擁塞避免算法

  網絡中擁塞的發生會導致數據分組丟失,需要儘量避免。在實際中,擁塞算法與慢啓動通常在一起實現,其基本過程:
   1. 對一個給定的連接,初始化cwnd爲1個報文段,ssthresh爲65535個字節。
   2. TCP輸出例程的輸出不能超過cwnd和接收方通告窗口的大小。擁塞避免是發送方使用 的流量控制,而通告窗口則是接收方進行的流量控制。前者是發送方感受到的網絡擁塞的估 計,而後者則與接收方在該連接上的可用緩存大小有關。
   3. 當擁塞發生時(超時或收到重複確認),ssthresh被設置爲當前窗口大小的一半(cwnd 和接收方通告窗口大小的最小值,但最少爲2個報文段)。此外,如果是超時引起了擁塞,則 cwnd被設置爲1個報文段(這就是慢啓動)。
   4. 當新的數據被對方確認時,就增加cwnd,但增加的方法依賴於是否正在進行慢啓動或擁塞避免。如果cwnd小於或等於ssthresh,則正 在進行慢啓動,否則正在進行擁塞避免。慢啓動一直持續到回到當擁塞發生時所處位置的半時候才停止(因爲記錄了在步驟2 中製造麻煩的窗口大小的一半),然後轉爲執行擁塞避免。
   慢啓動算法初始設置cwnd爲1個報文段,此後每收到一個確認就加 1。那樣,這會使窗口按指數方式增長:發送 1個報文段,然後是2個,接着是4個……。

這裏寫圖片描述

  在該圖中,假定當cwnd爲32個報文段時就會發生擁塞。於是設置 ssthresh爲16個報文段,而cwnd爲1個報文段。在時刻 0發送了一個報文段,並假定在時刻 1接收到它的ACK,此時cwnd增加爲2。接着發送了2個報文段,並假定在時刻 2接收到它們的ACK,於是cwnd增加爲4(對每個ACK增加1次)。這種指數增加算法一直進行到在時刻3和4之間收到8個ACK後cwnd等於ssthresh時才停止,從該時刻起,cwnd以線性方式增加,在每個往返時間內最多增加 1個報文段。

快速重傳和快速恢復算法

  這是數據丟包的情況下給出的一種修補機制。一般來說,重傳發生在超時之後,但是如果發送端接受到3個以上的重複ACK的情況下(上面的圖中第二個包丟失了,就收到了兩個相同的ack=11),就應該意識到,數據丟了,需要重新傳遞。這個機制是不需要等到重傳定時器溢出的,所以叫做快速重傳,它可以避免發送端因等待重傳計時器的超時而空閒較長時間,以此增加網絡吞吐量。而重新傳遞以後,因爲走的不是慢啓動而是擁塞避免算法,所以這又叫做快速恢復算法。算法流程如下:
  1. 當收到第3個重複的ACK時,將ssthresh設置爲當前擁塞窗口cwnd的一半。重傳丟失的報文段。設置cwnd爲ssthresh加上3倍的報文段大小。
  2. 每次收到另一個重複的ACK時, cwnd增加1個報文段大小併發送1個分組(如果新的cwnd允許發送)。
  3. 當下一個確認新數據的ACK到達時,設置cwnd爲ssthresh(在第1步中設置的值)。這個 ACK應該是在進行重傳後的一個往返時間內對步驟1中重傳的確認。另外,這個ACK也應該是對丟失的分組和收到的第1個重複的ACK之間的所有中間報文段 的確認。
  
更多參考:
http://baike.baidu.com/link?url=BNBotLOFxb1ReNROQGeqFZdpoSb8MbBJoY_P1xFMK6Qt7oDCBXLynprYbTrMf2fjk4YMMuAv-NJPo2Y1YpjWz_

TCP成塊數據流

參考:TCP的成塊數據流

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