什麼是擁塞?如何解決擁塞?
擁塞 :網絡中某資源資源的需求超過了該資源所能提供的可用部分
爲什麼增加資源不能解決擁塞?
簡單來說,出現擁塞就是:需求 > 供給
那麼增大供給量,不就可以解決擁塞了嗎?答案是否定的
因爲網絡是一個複雜的系統,如果出現擁塞,只增加資源是不能解決問題的,還有可能會使網絡性能更壞
例如:
- 當出現網絡擁塞,然後不斷增加資源,那麼路由器的緩存空間就會不足,從而丟棄一些分組,然後不斷重傳
- 那麼再增大路由器的緩存空間呢?還也只是可以解決此問題,但還會有更多的新問題產生
- 所以,單單增加資源,這並不能重根本上解決網絡擁塞問題
如何控制擁塞?
TCP採用基於擁塞窗口的方法進行擁塞控制,該方法屬於閉環控制方法
- 開環控制:在設計網絡時,事先將所有可能的發生擁塞的情況都考慮到,力求不產生擁塞
- 閉環控制:動態監測網絡系統,檢測擁塞並進行反饋、調整,以解決問題
擁塞窗口可以簡單理解爲一個窗口,每次發送數據的大小都限制在這個窗口的範圍之內
控制擁塞窗口的原則
- 只要網絡沒有出現擁塞,擁塞窗口就可以再增大一些
- 只要網絡出現擁塞或有可能出現擁塞,就將擁塞窗口減小一些
如何判斷出現了擁塞?
- 重傳定時器超時
- 收到三個重複的ACK
TCP擁塞控制算法
- 慢開始
- 擁塞避免
- 快重傳
- 快恢復
慢開始
由小到大逐漸增大擁塞窗口數值
- 擁塞窗口cwnd初始值:1
- 每經過一個傳輸輪次(往返時間),擁塞窗口cwnd就加倍(指數增長)
- 當增加到慢開始門限ssthresh時(cwnd > ssthresh),改爲擁塞避免算法
(當cwnd = ssthresh時,既可以用慢開始算法,也可疑用擁塞避免算法)
擁塞避免
讓擁塞窗口按線性規律緩慢的增大
- 每經過一個傳輸輪次,擁塞窗口cwnd加 1(慢開始算法是加倍)
直到網絡出現擁塞,當擁塞原因爲
- 超時:使 ssthresh = max(cwnd/2, 2)(在兩者之間取最大值),cwnd = 1,執行慢開始算法
- 收到三個重複的ACK:ssthresh = 當前擁塞窗口cwnd / 2,新擁塞窗口cwnd = 慢開始門限 ssthresh,執行擁塞避免算法
快重傳
當發送方收到連續三個重複的ACK時,就知道接收方確實沒有收到報文段,應立即進行快重傳算法,這樣就不會出現超時,發送方也就不會誤認爲出現了網絡擁塞
快恢復
當發送方收到連續三個重複的ACK時,執行快恢復算法
- 將慢開始門限ssthresh = 當前擁塞窗口cwnd / 2
- 新擁塞窗口cwnd = 慢開始門限ssthresh
- 然後執行擁塞避免算法
TCP擁塞控制流程圖
例題
1、試畫出擁塞窗口與傳輸輪次的關係曲線。
(此曲線採用python-matplotlib繪製)
2、指明TCP工作在慢開始階段的時間間隔。
- 【1-6】和【23-26】
3、指明TCP工作在擁塞避免階段的時間間隔。
- 【6-16】和【17-22】
4、在第16輪次和第22輪次之後發送方是通過收到三個重複的確認還是通過超時檢測到丟失了報文段?。
- 第16輪次收到的是三個重複的確認,因爲隨後執行的是快恢復,慢開始門限ssthresh = 當前擁塞窗口cwnd / 2,新擁塞窗口cwnd = 慢開始門限ssthresh,開始執行擁塞避免算法
- 第22輪次收到的是超時,因爲隨後擁塞窗口cwnd恢復到1
5、在第1輪次、第18輪次和第24輪次發送時,門限ssthresh分別被設置爲多大?。
- 第1輪次,門限值:32
- 第18輪次,門限值:21,(發生擁塞時的一半)
- 第24輪次,門限值:13(發送擁塞時的一半)
6、在第幾輪次發送出第70個報文段?。
- 在第7輪次發送出第70個報文段
7、假定在第26輪次之後收到了三個重複的確認,因而檢測出了報文段的丟失,那麼擁塞窗口cwnd和門限ssthresh應設置爲多大?。
- 擁塞窗口cwnd和門限ssthresh應設置爲:4,(因爲26輪次的擁塞值爲8,且收到三個重複的ACK,所以下一次設置爲一半)
擁塞控制與流量控制的區別
- 擁塞控制:全局性的過程,涉及所有主機、路由器,以及與降低網絡傳輸性能有關的所有因素,防止過多的數據注入到網絡中,使網絡的路由器或鏈路不致過載
- 流量控制:往往指點對點通信量的控制,是端到端的問題,所要做的就是抑制發送端發送數據的速率,以便使接收端來的及接收
加法增大、乘法減小
- 在擁塞避免階段,擁塞窗口是按照線性規律增大的,稱爲“加法增大”(AI)
- 當出現超時或連續三個重複的ACK時,就要把門限值設置爲當前擁塞窗口的一半,並大大減少擁塞窗口的數值,稱爲“乘法減小”(MD)
- 兩個合在一起就是AIMD算法
擁塞控制所起的作用
總結
擁塞控制是非常難設計的,因爲它是一個動態的問題
擁塞控制並不能完全解決擁塞問題,只是降低了擁塞的程度
真正的發送窗口值 = Min{接收方窗口值,擁塞窗口值}