TCP的擁塞控制是如何實(shí)現(xiàn)的?
面試官:請說一下,TCP的擁塞控制是如何實(shí)現(xiàn)的?
流量控制是避免發(fā)送方的數(shù)據(jù)填滿接收方的緩存。但計(jì)算機(jī)網(wǎng)絡(luò)一般都處在一個共享的環(huán)境,因此也有可能會因?yàn)槠渌鳈C(jī)之間的通信使得網(wǎng)絡(luò)擁堵。在網(wǎng)絡(luò)出現(xiàn)擁堵時,如果繼續(xù)發(fā)送大量數(shù)據(jù)包,可能會導(dǎo)致數(shù)據(jù)包丟失或者時延增大,這時TCP就會重傳數(shù)據(jù),而一重傳就會導(dǎo)致網(wǎng)絡(luò)的負(fù)擔(dān)更重,于是會導(dǎo)致更大的延遲和更多的丟包。
圖片
圖片
圖片
TCP的擁塞控制機(jī)制可以根據(jù)網(wǎng)絡(luò)鏈路的實(shí)時狀態(tài),自動調(diào)整發(fā)送速度,降低發(fā)送的數(shù)據(jù)量,從而避免發(fā)送方的數(shù)據(jù)填滿整個網(wǎng)絡(luò)。
圖片
圖片
圖片
TCP通過擁塞窗口來約束發(fā)送速度,擁塞窗口跟接收窗口類似,同樣規(guī)定了發(fā)送方此刻能夠發(fā)送出去的字節(jié)數(shù),只不過它是通過評估網(wǎng)絡(luò)鏈路的擁塞程度,并由一定的算法計(jì)算而來的。發(fā)送方的發(fā)送窗口大小由接收窗口和擁塞窗口共同決定,取擁塞窗口和接收窗口中的最小值。
圖片
TCP通過慢啟動、擁塞避免、擁塞發(fā)生和快速恢復(fù)四種算法來進(jìn)行擁塞控制。
圖片
1、慢啟動
TCP連接剛建立時,對網(wǎng)絡(luò)鏈路的運(yùn)行狀況一無所知,慢啟動就是TCP啟動后的發(fā)送速度慢慢的進(jìn)行提速,便于感知網(wǎng)絡(luò)的狀況。
圖片
慢啟動算法將擁塞窗口cwnd初始化為1,然后每收到一個ACK,cwnd就會加 1,假設(shè)每個報(bào)文段都會回復(fù)ACK確認(rèn),在沒有丟包的情況下,第一個分組被確認(rèn)后,cwnd就變成了2,接下來,TCP可以發(fā)送2個報(bào)文段。如果這2個報(bào)文段均順利送到,可以收到2個ACK確認(rèn),cwnd增大到 4,以此類推。因此,慢啟動期間cwnd是呈指數(shù)增長的。
圖片
圖片
2、擁塞避免
當(dāng)cwnd超過慢啟動門限ssthresh時就會進(jìn)入擁塞避免算法。在擁塞避免階段,TCP以更慢的速度擴(kuò)張擁塞窗口,每當(dāng)成功發(fā)送跟擁塞窗口大小等量的數(shù)據(jù)并收到ACK確認(rèn)后,cwnd就加1。例如,假設(shè)當(dāng)前擁塞窗口大小為k,這時可以發(fā)出k個報(bào)文段。當(dāng)這k個報(bào)文段均發(fā)出并收到確認(rèn)后,才給cwnd加1,所以擁塞避免階段,cwnd是呈線性增長的。
圖片
圖片
3、擁塞發(fā)生
進(jìn)入擁塞避免階段后,窗口保持緩慢增長,當(dāng)遇到網(wǎng)絡(luò)擁塞發(fā)送丟包時,TCP就會進(jìn)行重傳。如果是發(fā)生超時重傳,慢啟動門限ssthresh會被設(shè)置為當(dāng)前擁塞窗口值的一半,cwnd恢復(fù)為初始化值1,然后重新開始前面的慢啟動過程。如果是發(fā)生快速重傳(重復(fù)ACK),ssthresh和cwnd都會變?yōu)楫?dāng)前擁塞窗口值的一半,然后進(jìn)入到快速恢復(fù)階段。
圖片
圖片
圖片
圖片
4、快速恢復(fù)
在快速恢復(fù)階段,發(fā)送方會重傳丟失的數(shù)據(jù)包,此時發(fā)送方已收到了3個重復(fù)的ACK,所以cwnd加3,如果再收到重復(fù)的 ACK,那么cwnd增加 1,如果收到新的ACK,表明重傳的包成功了,將cwnd設(shè)置為當(dāng)前的慢啟動門限ssthresh值,然后再次進(jìn)入到擁塞避免階段。