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