上篇文章講了TCP擁塞控制機制的原理,沒看過的不妨看下:5分鍾讀懂擁塞控制,這篇文章講講TCP流量控制機制。
一、為什么需要流量控制?
雙方在通信的時候,發送方的速率與接收方的速率是不一定相等,如果發送方的發送速率太快,會導致接收方處理不過來,這時候接收方只能把處理不過來的數據存在緩存區里(失序的數據包也會被存放在緩存區里)。
如果緩存區滿了發送方還在瘋狂着發送數據,接收方只能把收到的數據包丟掉,大量的丟包會極大着浪費網絡資源,因此,我們需要控制發送方的發送速率,讓接收方與發送方處於一種動態平衡才好。
對發送方發送速率的控制,我們稱之為流量控制。
二、如何控制?
接收方每次收到數據包,可以在發送確定報文的時候,同時告訴發送方自己的緩存區還剩余多少是空閑的,我們也把緩存區的剩余大小稱之為接收窗口大小,用變量win來表示接收窗口的大小。
發送方收到之后,便會調整自己的發送速率,也就是調整自己發送窗口的大小,當發送方收到接收窗口的大小為0時,發送方就會停止發送數據,防止出現大量丟包情況的發生。
三、發送方何時再繼續發送數據?
當發送方停止發送數據后,該怎樣才能知道自己可以繼續發送數據?
我們可以采用這樣的策略:當接收方處理好數據,接受窗口 win > 0 時,接收方發個通知報文去通知發送方,告訴他可以繼續發送數據了。當發送方收到窗口大於0的報文時,就繼續發送數據。
不過這時候可能會遇到一個問題,假如接收方發送的通知報文,由於某種網絡原因,這個報文丟失了,這時候就會引發一個問題:接收方發了通知報文后,繼續等待發送方發送數據,而發送方則在等待接收方的通知報文,此時雙方會陷入一種僵局。
為了解決這種問題,我們采用了另外一種策略:當發送方收到接受窗口 win = 0 時,這時發送方停止發送報文,並且同時開啟一個定時器,每隔一段時間就發個測試報文去詢問接收方,打聽是否可以繼續發送數據了,如果可以,接收方就告訴他此時接受窗口的大小;如果接受窗口大小還是為0,則發送方再次刷新啟動定時器。
四、一些術語及其注意點說明
1、這里說明下,由於TCP/IP支持全雙工傳輸,因此通信的雙方都擁有兩個滑動窗口,一個用於接受數據,稱之為接收窗口;一個用於發送數據,稱之為擁塞窗口(即發送窗口)。指出接受窗口大小的通知我們稱之為窗口通告。
2、接收窗口的大小固定嗎?
在早期的TCP協議中,接受接受窗口的大小確實是固定的,不過隨着網絡的快速發展,固定大小的窗口太不靈活了,成為TCP性能瓶頸之一,也就是說,在現在的TCP協議中,接受窗口的大小是根據某種算法動態調整的。
3、接受窗口越大越好嗎?
接受窗口如果太小的話,顯然這是不行的,這會嚴重浪費鏈路利用率,增加丟包率。那是否越大越好呢?答否,當接收窗口達到某個值的時候,再增大的話也不怎么會減少丟包率的了,而且還會更加消耗內存。所以接收窗口的大小必須根據網絡環境以及發送發的的擁塞窗口來動態調整。
4、發送窗口和接受窗口相等嗎?
接收方在發送確認報文的時候,會告訴發送發自己的接收窗口大小,而發送方的發送窗口會據此來設置自己的發送窗口,但這並不意味着他們就會相等。首先接收方把確認報文發出去的那一刻,就已經在一邊處理堆在自己緩存區的數據了,所以一般情況下接收窗口 >= 發送窗口。
我這篇文章算是可以讓你知道流量控制的大致原理,如果你想知道更多細節,可以參考TCP/IP詳解這本書,挺不錯。文章若有錯誤,還望后台留言指點下,謝謝。
推薦閱讀:
更多原創文章可以關注我的公眾號:苦逼的碼農(ID:201805)