TCP 滑動(dòng)窗口(已經(jīng)發(fā)出等待對(duì)方確認(rèn)的隊(duì)列)協(xié)議
滑動(dòng)窗口協(xié)議是TCP使用的一種流量控制方法,該協(xié)議允許發(fā)送方在停止并等待確認(rèn)前可以連續(xù)發(fā)送多個(gè)分組。TCP是如何通過滑動(dòng)窗口協(xié)議實(shí)現(xiàn)流量控制的?本博文將為您詳細(xì)介紹該協(xié)議及其工作原理。
什么是滑動(dòng)窗口協(xié)議?
一圖勝千言,看下面的圖。簡單解釋下,發(fā)送和接受方都會(huì)維護(hù)一個(gè)數(shù)據(jù)幀的序列,這個(gè)序列被稱作窗口。發(fā)送方的窗口大小由接受方確定,目的在于控制發(fā)送速度,以免接受方的緩存不夠大,而導(dǎo)致溢出,同時(shí)控制流量也可以避免網(wǎng)絡(luò)擁塞。下面圖中的4,5,6號(hào)數(shù)據(jù)幀已經(jīng)被發(fā)送出去,但是未收到關(guān)聯(lián)的ACK,7,8,9幀則是等待發(fā)送??梢钥闯霭l(fā)送端的窗口大小為6,這是由接受端告知的(事實(shí)上必須考慮擁塞窗口cwnd,這里暫且考慮cwnd>rwnd)。此時(shí)如果發(fā)送端收到4號(hào)ACK,則窗口的左邊緣向右收縮,窗口的右邊緣則向右擴(kuò)展,此時(shí)窗口就向前“滑動(dòng)了”,即數(shù)據(jù)幀10也可以被發(fā)送。
下面就滑動(dòng)窗口協(xié)議做出更詳細(xì)的說明,這里為了簡單起見設(shè)定發(fā)送方窗口大小為2,接受方大小為1??聪旅鎴D:
一:初始態(tài),發(fā)送方?jīng)]有幀發(fā)出,發(fā)送窗口前后沿相重合。接收方0號(hào)窗口打開,等待接收0號(hào)幀;
二:發(fā)送方打開0號(hào)窗口,表示已發(fā)出0幀但尚確認(rèn)返回信息。 此時(shí)接收窗口狀態(tài)不變;
三:發(fā)送方打開0、1號(hào)窗口,表示0、1號(hào)幀均在等待確認(rèn)之列。至此,發(fā)送方打開的窗口數(shù)已達(dá)規(guī)定限度,在未收到新的確認(rèn)返回幀之 前,發(fā)送方將暫停發(fā)送新的數(shù)據(jù)幀。接收窗口此時(shí)狀態(tài)仍未變;
四:接收方已收到0號(hào)幀,0號(hào)窗口關(guān)閉,1號(hào)窗口打開,表示準(zhǔn)備接收1號(hào)幀。此時(shí)發(fā)送窗口狀態(tài)不 變;
五:發(fā)送方收到接收方發(fā)來的0號(hào)幀確認(rèn)返回信息,關(guān)閉0號(hào)窗口,表示從重發(fā)表中刪除0號(hào)幀。此時(shí)接收窗口狀態(tài)仍不變
六:發(fā)送方繼續(xù)發(fā)送2號(hào)幀,2號(hào)窗口 打開,表示2號(hào)幀也納入待確認(rèn)之列。至此,發(fā)送方打開的窗口又已達(dá)規(guī)定限度,在未收到新的確認(rèn)返回幀之前,發(fā)送方將暫停發(fā)送新的數(shù)據(jù)幀,此時(shí)接收窗口狀態(tài) 仍不變;
七:接收方已收到1號(hào)幀,1號(hào)窗口關(guān)閉,2號(hào)窗口打開,表示準(zhǔn)備接收2號(hào)幀。此時(shí)發(fā)送窗口狀態(tài)不變;
八:發(fā)送方收到接收方發(fā)來的1號(hào)幀收畢的確認(rèn)信 息,關(guān)閉1號(hào)窗口,表示從重發(fā)表中刪除1號(hào)幀。此時(shí)接收窗口狀態(tài)仍不變。
1比特滑動(dòng)窗口協(xié)議?
上面說的只是滑動(dòng)窗口協(xié)議的理論,實(shí)際應(yīng)用中又有不同。首先就是停等協(xié)議(stop-and-wait),這時(shí)接受方的窗口和發(fā)送方的窗口大小都是1,1個(gè)比特就夠表示了,所以也叫1比特滑動(dòng)窗口協(xié)議。發(fā)送方這時(shí)自然發(fā)送每次只能發(fā)送一個(gè),并且必須等待這個(gè)數(shù)據(jù)包的ACK,才能發(fā)送下一個(gè)。雖然在效率上比較低,帶寬利用率明顯較低,不過在網(wǎng)絡(luò)環(huán)境較差,或是帶寬本身很低的情況下,還是適用的??聪旅娴牧鞒虉D:
后退n協(xié)議?
停等協(xié)議雖然實(shí)現(xiàn)簡單,也能較好的適用惡劣的網(wǎng)絡(luò)環(huán)境,但是顯然效率太低。所以有了后退n協(xié)議,這也是滑動(dòng)窗口協(xié)議真正的用處,這里發(fā)送的窗口大小為n,接受方的窗口仍然為1。具體看下面的圖,這里假設(shè)n=9:
首先發(fā)送方一口氣發(fā)送10個(gè)數(shù)據(jù)幀,前面兩個(gè)幀正確返回了,數(shù)據(jù)幀2出現(xiàn)了錯(cuò)誤,這時(shí)發(fā)送方被迫重新發(fā)送2-8這7個(gè)幀,接受方也必須丟棄之前接受的3-8這幾個(gè)幀。
后退n協(xié)議的好處無疑是提高了效率,但是一旦網(wǎng)絡(luò)情況糟糕,則會(huì)導(dǎo)致大量數(shù)據(jù)重發(fā),反而不如上面的停等協(xié)議,實(shí)際上這是很常見的,具體可以參考TCP擁塞控制。
選擇重傳協(xié)議?
后退n協(xié)議的另外一個(gè)問題是,當(dāng)有錯(cuò)誤幀出現(xiàn)后,總是要重發(fā)該幀之后的所有幀,毫無疑問在網(wǎng)絡(luò)不是很好的情況下會(huì)進(jìn)一步惡化網(wǎng)絡(luò)狀況,重傳協(xié)議便是用來解決這個(gè)問題。原理也很簡單,接收端總會(huì)緩存所有收到的幀,當(dāng)某個(gè)幀出現(xiàn)錯(cuò)誤時(shí),只會(huì)要求重傳這一個(gè)幀,只有當(dāng)某個(gè)序號(hào)后的所有幀都正確收到后,才會(huì)一起提交給高層應(yīng)用。重傳協(xié)議的缺點(diǎn)在于接受端需要更多的緩存。
原文鏈接:http://blog.chinaunix.net/uid-24517549-id-3991562.html