TCP 有序傳輸,擁塞機制,重傳機制

原文鏈接:https://blog.csdn.net/ggxxkkll/article/details/7894112

通過怎樣的方式來保證數據的順序化傳輸?

主機每次發送數據時,TCP就給每個數據包分配一個序列號並且在一個特定的時間內等待接收主機對分配的這個序列號進行確認,如果發送主機在一個特定時間內沒有收到接收主機的確認,則發送主機會重傳此數據包。接收主機利用序列號對接收的數據進行確認,以便檢測對方發送的數據是否有丟失或者亂序等,接收主機一旦收到已經順序化的數據,它就將這些數據按正確的順序重組成數據流並傳遞到高層進行處理。

如何保證傳輸可靠性

當TCP發出一個數據後,它啓動一個定時器,等待目的端確認收到這個報文段。如果不能及時收到一個確認,將重發這個報文段。在未收到確認之前,這些已經發送的數據報將留在發送緩衝區,直到收到確認之後才清除已發送的數據。

(1)爲了保證數據包的可靠傳遞,發送方必須把已發送的數據包保留在緩衝區; 

(2)併爲每個已發送的數據包啓動一個超時定時器; 

(3)如在定時器超時之前收到了對方發來的應答信息(可能是對本包的應答,也可以是對本包後續包的應答),則釋放該數據包占用的緩衝區; 

(4)否則,重傳該數據包,直到收到應答或重傳次數超過規定的最大次數爲止。

(5)接收方收到數據包後,先進行CRC校驗,如果正確則把數據交給上層協議,然後給發送方發送一個累計應答包,表明該數據已收到,如果接收方正好也有數據要發給發送方,應答包也可方在數據包中捎帶過去。
 

擁塞機制

我們知道TCP是擁有擁塞控制機制的,而UDP是沒有的,爲什麼需要擁塞控制機制呢,就是防止丟包過多導致傳輸效率低下。網絡中傳輸的包太多,路由器的緩存又不夠,每一個發送端都以自己想要的發送速率發送包,自然會導致網絡擁塞。所以TCP就包括了擁塞控制機制。

有幾種擁塞控制方法?

1. 端到端擁塞控制。

網絡層沒有顯示的告知傳輸層此時網絡出現擁塞了,傳輸層通過報文段的丟失(超時或3次冗餘確認得知)認爲網絡出現擁塞了,TCP會縮減其擁塞窗口,減小發送速率。

2. 網絡輔助的擁塞控制。

網絡層顯示的告知發送端此時網絡擁塞了,少發點。

有兩種告知方式:

  •   直接反饋信息可以由網絡路由器發送給發送端,採用阻塞分組的形式。
  •   路由器標記或更新從發送端向接收方的分組中的某個字段來指示擁塞產生。一旦受到一個標記的分組後,接收方就會向發送方通知該網絡阻塞指示。

TCP採用的是第一種方式,也就是端到端的擁塞控制。

 

端到端擁塞控制機制的實現?

首先明確下,發生端會通過設置一個擁塞窗口(congestion window   cwnd),有點像可靠性傳輸中的滑動窗口,維持窗口的大小,窗口越大代表你發送的速率越快,發送的字節越多。

其中有3種擁塞控制算法:慢啓動( slow-start )、擁塞避免( congestion avoidance )、快重傳( fast retransmit )和快速恢復( fast recovery )。

1.慢啓動

當新建TCP連接時,cwnd初始化設爲1個最大報文段(MSS)大小,發送端開始按照擁塞窗口大小發送數據,每當有一個報文段被確認,cwnd就增加1個MSS大小。這樣cwnd的值就隨着網絡往返時間(Round Trip Time,RTT)呈指數級增長,事實上,慢啓動的速度一點也不慢,只是它的起點比較低一點而已。我們可以簡單計算下:

   開始           --->     cwnd = 1

   經過1個RTT後   --->     cwnd = 2*1 = 2

   經過2個RTT後   --->     cwnd = 2*2= 4

   經過3個RTT後   --->     cwnd = 4*2 = 8

由此可見慢啓動的增長速度很快,cwnd也會指數增長,那你會不會有疑問,那這種指數增長啥時候停止呢?

有3中情況會讓慢啓動停止:

1.TCP使用了一個叫慢啓動閥門值(ssthresh)的變量,當cwnd超過該值後,慢啓動過程結束,進入擁塞避免階段。對於大多數TCP實現來說,ssthresh的值是65536(同樣以字節計算)。

2.超時丟包事件發生。TCP發送方將cwnd設置爲1,慢啓動閥門值(ssthresh)設置爲cwnd/2,並重新開始慢啓動過程。

3.檢測到3個冗餘的ACK。這時TCP執行一種快速重傳並進入快速恢復狀態。

 

2.擁塞避免

一旦進入到擁塞避免,則說明cwnd目前的值裏擁塞可能並不遙遠了,你就不應該使用慢啓動那種指數增長的方式擴展cwnd,此時用的是較爲保守的方式,每個RTT只是將cwnd的值增加1個MSS。

那什麼時候結束擁塞避免呢?

1.出現超時丟包。cwnd值被設置爲1個MSS大小,慢啓動閥門值(ssthresh)被設置爲cwnd/2。

2.3個冗餘的ACK。不改變發送速率。

 

3.快速恢復

1.當收到3個冗餘的ACK時,把ssthresh設置爲cwnd的一半,把cwnd設置爲ssthresh的值加3,然後重傳丟失的報文段,加3的原因是因爲收到3個重複的ACK,表明有3個“老”的數據包離開了網絡。 
2.再收到重複的ACK時,擁塞窗口增加1。 
3.當收到新的數據包的ACK時,把cwnd設置爲第一步中的ssthresh的值。原因是因爲該ACK確認了新的數據,說明從重複ACK時的數據都已收到,該恢復過程已經結束,可以回到恢復之前的狀態了,也即再次進入擁塞避免狀態。注意,如果在此過程出現超時,則重新進入慢啓動階段。

 

 

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