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