計算機網絡中的帶寬、交換結點中的緩存和處理機等,都是網絡的資源。在某段時間,若對網絡中某一資源的需求超過了該資源所能提供的可用部分,網絡的性能就會變壞。這種情況就叫做擁塞。
擁塞控制就是防止過多的數據注入網絡中,這樣可以使網絡中的路由器或鏈路不致過載。和流量控制不同,擁塞控制是一個全局性的過程,而流量控制是點對點通信量的控制。
慢啟動算法與擁塞避免算法
擁塞避免算法的前提是:假定由于分組受到損壞引起的丟失是非常少的,因此分組丟失(發(fā)生超時和接收到重復的確認)就意味著在源主機和目的主機之間的某處網絡發(fā)生了擁塞
慢啟動算法為發(fā)送方的TCP增加了另一個窗口:擁塞窗口,記為cwnd。
與另一個網絡的主機建立TCP連接時,擁塞窗口被初始化為1個報文段(即另一端通告的報文段大小),每收到一個ACK,擁塞窗口就增加一個報文段。
實現
為了防止cwnd增長過大引起網絡擁塞,還需設置一個慢開始門限ssthresh狀態(tài)變量。
ssthresh 的用法如下:
- 當cwnd < ssthresh時,使用慢開始算法。
- 當cwnd > ssthresh時,改用擁塞避免算法。
- 當cwnd = ssthresh時,慢啟動與擁塞避免算法任意。

無論是在慢開始階段還是在擁塞避免階段,只要發(fā)送方判斷網絡出現擁塞(其根據就是沒有收到確認ACK,雖然沒有收到確認可能是其他原因,但是因為無法判定,所以都當做擁塞來處理),就把慢開始門限設置為出現擁塞時的發(fā)送窗口大小的一半。然后把擁塞窗口設置為1,執(zhí)行慢開始算法。
快速重傳算法
超時重傳是TCP協議保證數據可靠性的一個重要機制,其原理是在發(fā)送一個數據以后就開啟一個計時器。在一定時間內如果沒有得到發(fā)送數據報的ACK報文,那么就重新發(fā)送數據,直到發(fā)送成功為止。
這是數據包丟失的情況下給出的一種修補機制。一般來說,重傳發(fā)生在超時之后,但是如果發(fā)送端接收到3個以上的重復ACK,就應該意識到,數據丟了,需要重新傳遞。這個機制不需要等到重傳定時器溢出,所以叫做快速重傳。
而快速重傳以后,因為走的不是慢啟動而是擁塞避免算法,所以這又叫做快速恢復算法。
- 為什么需要收到3個以上的重復ACK,才會執(zhí)行快速重傳?
在沒有快速重傳和快速恢復的算法之前,重傳依靠發(fā)送方的retransmit timeout,就在timeout內如果沒有接收到對方的ACK,默認包丟失,發(fā)送方就重傳。
包丟失的原因:
- 包 checksum 出錯
- 網絡擁塞
- 網絡斷,包括路由重收斂。
但是無法判斷是 哪一種算法,于是采用最笨的方法,就是將自己的發(fā)送速率減半,即cwnd/2,這樣的方法對2是有效的。可以緩解網絡擁塞。
但是對于1來說,丟包是因為偶爾出錯引起的,一丟包就對半減速不合理。于是有了快速重傳算法,基于在反向還可以接收到ACK,可以認為網絡并沒有斷,否則也接收不到ACK,如果在timeout時間內沒有接收到>2的重復的 ACK,則大概率是亂序。而如果收到3個或2個以上的duplicated ACK,則大概率是丟包。