TCP的阻塞機制

來源:互聯網
上載者:User

http://blog.sina.com.cn/s/blog_6014909d0100k8uo.html

TCP 的擁塞機制
TCP的擁塞機制包括四個

慢啟動
擁塞規避
快速啟動
快速恢複

下面一個一個的具體說明:

(一下為我在網路上摘錄的,關於TCP阻塞機制的文章。)

為了防止網路的擁塞現象,TCP提出了一系列的擁塞控制機制。最初由V. Jacobson在1988年的論文中提出的TCP的擁塞控制由“慢啟動(Slow start)”和“擁塞避免(Congestion avoidance)”組成,後來TCP Reno版本中又針對性的加入了“快速重傳(Fast retransmit)”、“快速恢複(Fast Recovery)”演算法,再後來在TCP NewReno中又對“快速恢複”演算法進行了改進,近些年又出現了選擇性應答( selective acknowledgement,SACK)演算法,還有其他方面的大大小小的改進,成為網路研究的一個熱點。

TCP的擁塞控制主要原理依賴於一個擁塞視窗(cwnd)來控制,在之前我們還討論過TCP還有一個對端通告的接收視窗(rwnd)用於流量控制。視窗值的大小就代表能夠發送出去的但還沒有收到ACK的最大資料報文段,顯然視窗越大那麼資料發送的速度也就越快,但是也有越可能使得網路出現擁塞,如果視窗值為1,那麼就簡化為一個停等協議,每發送一個資料,都要等到對方的確認才能發送第二個資料包,顯然資料轉送效率低下。TCP的擁塞控制演算法就是要在這兩者之間權衡,選取最好的cwnd值,從而使得網路輸送量最大化且不產生擁塞。

由於需要考慮擁塞控制和流量控制兩個方面的內容,因此TCP的真正的發送視窗=min(rwnd, cwnd)。但是rwnd是由對端確定的,網路環境對其沒有影響,所以在考慮擁塞的時候我們一般不考慮rwnd的值,我們暫時只討論如何確定cwnd值的大小。關於cwnd的單位,在TCP中是以位元組來做單位的,我們假設TCP每次傳輸都是按照MSS大小來發送資料的,因此你可以認為cwnd按照資料包個數來做單位也可以理解,所以有時我們說cwnd增加1也就是相當於位元組數增加1個MSS大小。

慢啟動:最初的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

如果頻寬為W,那麼經過RTT*log2W時間就可以佔滿頻寬。

擁塞避免:從慢啟動可以看到,cwnd可以很快的增長上來,從而最大程度利用網路頻寬資源,但是cwnd不能一直這樣無限增長下去,一定需要某個限制。TCP使用了一個叫慢啟動門限(ssthresh)的變數,當cwnd超過該值後,慢啟動過程結束,進入擁塞避免階段。對於大多數TCP實現來說,ssthresh的值是65536(同樣以位元組計算)。擁塞避免的主要思想是加法增大,也就是cwnd的值不再指數級往上升,開始加法增加。此時當視窗中所有的報文段都被確認時,cwnd的大小加1,cwnd的值就隨著RTT開始線性增加,這樣就可以避免增長過快導致網路擁塞,慢慢的增加調整到網路的最佳值。

上面討論的兩個機制都是沒有檢測到擁塞的情況下的行為,那麼當發現擁塞了cwnd又該怎樣去調整呢?

首先來看TCP是如何確定網路進入了擁塞狀態的,TCP認為網路擁塞的主要依據是它重傳了一個報文段。上面提到過,TCP對每一個報文段都有一個定時器,稱為重傳定時器(RTO),當RTO逾時且還沒有得到資料確認,那麼TCP就會對該報文段進行重傳,當發生逾時時,那麼出現擁塞的可能性就很大,某個報文段可能在網路中某處丟失,並且後續的報文段也沒有了訊息,在這種情況下,TCP反應比較“強烈”:

1.把ssthresh降低為cwnd值的一半

2.把cwnd重新設定為1

3.重新進入慢啟動過程。

從整體上來講,TCP擁塞控制視窗變化的原則是AIMD原則,即加法增大、乘法減小。可以看出TCP的該原則可以較好地保證流之間的公平性,因為一旦出現丟包,那麼立即減半退避,可以給其他建立的流留有足夠的空間,從而保證整個的公平性。

其實TCP還有一種情況會進行重傳:那就是收到3個相同的ACK。TCP在收到亂序到達包時就會立即發送ACK,TCP利用3個相同的ACK來判定資料包的丟失,此時進行快速重傳,快速重傳做的事情有:

1.把ssthresh設定為cwnd的一半

2.把cwnd再設定為ssthresh的值(具體實現有些為ssthresh+3)

3.重新進入擁塞避免階段。

後來的“快速恢複”演算法是在上述的“快速重傳”演算法後添加的,當收到3個重複ACK時,TCP最後進入的不是擁塞避免階段,而是快速恢複階段。快速重傳和快速恢複演算法一般同時使用。快速恢複的思想是“資料包守恒”原則,即同一個時刻在網路中的資料包數量是恒定的,只有當“老”資料包離開了網路後,才能向網路中發送一個“新”的資料包,如果發送方收到一個重複的ACK,那麼根據TCP的ACK機制就表明有一個資料包離開了網路,於是cwnd加1。如果能夠嚴格按照該原則那麼網路中很少會發生擁塞,事實上擁塞控制的目的也就在修正違反該原則的地方。

具體來說快速恢複的主要步驟是:

1.當收到3個重複ACK時,把ssthresh設定為cwnd的一半,把cwnd設定為ssthresh的值加3,然後重傳丟失的報文段,加3的原因是因為收到3個重複的ACK,表明有3個“老”的資料包離開了網路。

2.再收到重複的ACK時,擁塞視窗增加1。

3.當收到新的資料包的ACK時,把cwnd設定為第一步中的ssthresh的值。原因是因為該ACK確認了新的資料,說明從重複ACK時的資料都已收到,該恢複過程已經結束,可以回到恢複之前的狀態了,也即再次進入擁塞避免狀態。

快速重傳演算法首次出現在4.3BSD的Tahoe版本,快速恢複首次出現在4.3BSD的Reno版本,也稱之為Reno版的TCP擁塞控制演算法。

可以看出Reno的快速重傳演算法是針對一個包的重傳情況的,然而在實際中,一個重傳逾時可能導致許多的資料包的重傳,因此當多個資料包從一個資料視窗中丟失時並且觸發快速重傳和快速恢複演算法時,問題就產生了。因此NewReno出現了,它在Reno快速恢複的基礎上稍加了修改,可以恢複一個視窗內多個包丟失的情況。具體來講就是:Reno在收到一個新的資料的ACK時就退出了快速恢複狀態了,而NewReno需要收到該視窗內所有資料包的確認後才會退出快速恢複狀態,從而更一步提高輸送量。

SACK就是改變TCP的確認機制,最初的TCP只確認當前已連續收到的資料,SACK則把亂序等資訊會全部告訴對方,從而減少資料發送方重傳的盲目性。比如說序號1,2,3,5,7的資料收到了,那麼普通的ACK只會確認序號4,而SACK會把當前的5,7已經收到的資訊在SACK選項裡面告知對端,從而提高效能,當使用SACK的時候,NewReno演算法可以不使用,因為SACK本身攜帶的資訊就可以使得發送方有足夠的資訊來知道需要重傳哪些包,而不需要重傳哪些包。

你也可以參考下<電腦網路>和<TCP/IP詳解>都有介紹

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.