天天看點

用文字描述TCP的流量控制和擁塞控制

TCP在發送端和接收端有兩個視窗,發送端的是擁塞視窗而接收端的就叫做接收視窗,兩個視窗的作用不同 ,所謂的流量控制就是收發端的速率要比對,決定權在接收端而不在發送端,因為發送的慢了可以提速,而 接收不了就意味着丢包,這就好比冷了可以穿衣而熱了隻有扒皮一樣。是以對于收發端,流量控制主要由接 收端控制,是以接收視窗就表示“我能接收多少”,按照這個數字發送,在該連接配接獨占網絡并且帶寬無限的 情況下流量是平滑的。接收端的接收視窗将按照自己的能力向前滑動。 然而網絡環境不是那麼理想的,第一任何連接配接不能獨占帶寬,第二,帶寬也不是無限,是以即使接收 端建議發送端發送多少資料,發送端也有確定公平的義務,是以發送端也有一個視窗,叫做擁塞視窗,指當 前的網絡狀況隻能發送這麼多資料報,一般發送端可以發送的資料是接收視窗和擁塞視窗的最小值,由于 tcp是全雙工的協定,連接配接兩端都是接收者和發送者,是以每端都有兩個視窗,其中的擁塞視窗和實際的發 送視窗自己維護,而接收視窗要在tcp協定頭中傳給對方,讓對方根據這個視窗和自己的擁塞視窗抉擇自己 的實際發送視窗。

1.慢啟動并不慢

慢啟動是一種擁塞控制機制,隻影響擁塞視窗,注意,實際的發送視窗需要取擁塞視窗和對端傳來的接收窗 口的最小值,慢啟動的過程中,擁塞視窗不斷增加,因為tcp連接配接剛啟動,并不知道網絡的實際情況,需要 用一種試探的方式慢慢平滑增加發送視窗的大小,增加的過程是十分快的,是指數增長的,直到發生擁塞或 者達到事前配置好的一個閥值,如是是擁塞發生了,那麼肯定要調整擁塞視窗了,事實上由于慢啟動實際很 快,如果僅僅有慢啟動,那麼網絡很快就擁堵不堪了。

2.擁塞發現

每一個資料報都有一個定時器,如果定時器逾時還沒有ack回來,那麼就說明該資料沒有到達目的地,十有 八九是網絡擁塞了,tcp的設計者必須假定網絡交通事故率很低,此時tcp發送端将采取措施,最重要的就是 重新開始慢啟動,并且将慢啟動閥值減小,當擁塞視窗到達該閥值的時候(由于閥值減小了,肯定比剛開始 的慢啟動過程先到這種狀态),實行另一種擁塞控制方法--擁塞避免,就是擁塞避免,其實就是将慢啟動的 指數增加視窗大小改為線性增加,進而漸漸将擁塞視窗調整到一個合适的大小。

3.快速重傳

還有一種情況會直接使用擁塞避免,那就是當發送端收到三個重複的ack的時候,說明接收端收到了三個序 列号靠後資料報,但都不是接收視窗最前面的那個,是以說明那個資料十有八九是丢了,是以可以預測擁塞 發生了,是以将擁塞視窗減半,然後線性增加,這就是加增乘減原則。順便,tcp接收資料的順序隻要在窗 口内并不一定非要按序,隻要OS的協定棧實作支援緩存視窗内的斷序資料即可。

4.加增乘減原則

該原則展現了公平,因為擁塞視窗增加隻會優惠到自己,而減小卻會優惠很多别的連接配接,每一個連接配接都有維 護公平的義務,本着優惠均等的原則,自己的行為應該讓包括自己在内的所有連接配接得到均等的實惠,是以優 惠隻有一個自己的時候用加法,而優惠很多大家的時候用乘法。

5.快速恢複算法

快速重傳雖然通過減半擁塞視窗的辦法可以減緩擁塞,但是自己過分的讓步可能會引起别人貪婪地掠奪,雖 然我讓步了,減半了擁塞視窗,但是我是靠接收了三個重複ack才得到這個消息的,而不是一個包的逾時, 如果在第一個重複ack時我就開始快速重傳,那麼此時我的擁塞視窗已經加了三個了,是以需要補償我無辜 的等待三個ack,是以快速恢複過程是對快速重傳的修正,将擁塞視窗減半後加上了3

6.擁塞視窗何時穩定

如果僅僅考慮擁塞控制,那麼貌似擁塞視窗會一直這麼指數增-乘減-加增-乘減-指數增-...循環下去,是的 ,确實是這樣,但是通過統計tcp連接配接的速率和流量,發現并不是這樣,而是發送端的視窗總是會穩定于一 個特定的值,而該值就是接受方的接收視窗的大小,最終,一切都被定格在了接收方的協定棧處理性能以及 緩沖區記憶體情況了,擁塞視窗隻要增加到接收方的接收視窗就不再增加和減少了,除非接收視窗增加或者減 小以及擁塞發生了,總之,擁塞視窗和接收視窗的最小值決定發送視窗,如果擁塞視窗增加到了接收視窗的 大小就不再繼續慢啟動或者擁塞避免。

7.網絡裝置和端機的能力

tcp的流量控制在端機,而擁塞卻取決于中間的路由器等網絡裝置以及網線,它們處理能力的比對至關重要 ,雖然端機遠遠不敵中間裝置,可是中間裝置卻由多數端機分享,試想如果端機的性能超越了網絡裝置,那 麼流量控制視窗将會很大,如此擁塞視窗将在增加到流控視窗之前出現擁塞,如此一來将會導緻頻繁調整發 送視窗,流控視窗也就失去了意義,雖然接收端能收那麼多資料,可是發送端卻怎麼也到不了該制高點,雖 然到不了但是還是會不懈的慢啟動-擁塞停等-快速重傳-...俨然網絡上的西西弗斯神話。

8.tcp是全雙工不停等的

如果按照很多教科書上所講的方式了解tcp,那麼tcp就是一個半雙工的協定,一方在發送了資料之後必須等 待确認才能繼續發送,就是一問一答式,可是看一下tcp的協定頭,包含一個ack字段和seq字段,這就說明 tcp可以在發送資料的時候将ack一同捎帶過來,正是如此它才是全雙工的。另外它也不是一個單純的停等協 議,而是基于視窗機制的批量發送/确認協定。

9.一個比喻

開車的人或者看過司機開車都知道,汽車的性能和道路的路況(擁塞程度和限速等)以及司機的技術水準共同 決定車能開多快,如果情況一,路況不好(擁塞控制),那麼再好的車再好的司機都會不停的做刹車,踩油門 ,換檔等動作,所有車都一樣,看起來不夠穩定,如果情況二,路況好,司機也好,但車不好(流量控制), 雖然很穩定,但白瞎了這條路和司機了,如果情況三,路好,車好,司機不夠娴熟(流量控制),司機的動作 和第一種情況一樣,但是好的司機卻不這樣。情況一指的是網絡裝置不好,情況二指的是端機不好,情況三 可能是下面的情況,端機好,可是端機上的諸如記憶體管理算法之類的軟性能很糟糕。

 本文轉自 dog250 51CTO部落格,原文連結:http://blog.51cto.com/dog250/1271805

繼續閱讀