【前言】上一篇文章介紹了關於TCP的基礎知識,以及創建(釋放)鏈接和滑動窗口的概念。
本篇文章將延續上一篇的思路,繼續介紹TCP實現可靠傳輸的機制。html
上一篇文章裏介紹過TCP採用中止等待協議,即在收到接收方的確認信息後才繼續發送下面的數據。
那麼若是(在一段時間內)發送方沒有收到確認信息,咱們即可以認爲數據在傳輸的過程當中出了差錯,沒有順利傳送到接收方。這種狀況下,就須要一個「超時重傳」的機制了。算法
TCP 每發送一個報文段,就對這個報文段設置一次計時器。只要計時器設置的重傳時間到但尚未收到確認,就要重傳這一報文段。網絡
那麼如何肯定重傳時間呢?這是TCP最複雜的問題之一。性能
爲了獲得較爲合理的重傳時間,TCP 採用了一種自適應算法。
學習
該算法中最關鍵的就是往返時間(RTT)的測量。
測量往返時間時,因爲有的報文通過重傳後,沒法判斷收到的確認報文是重傳報文的確認報文仍是原報文的確認報文,故採用了Karn算法:動畫
在研究擁塞控制的機制前,咱們首先須要對「擁塞」的概念有所瞭解。設計
在某段時間,若對網絡中某資源的需求超過了該資源所能提供的可用部分,網絡的性能就要變壞。這種現象稱爲擁塞 (congestion)。
若網絡中有許多資源同時產生擁塞,網絡的性能就要明顯變壞,整個網絡的吞吐量將隨輸入負荷的增大而降低。3d
「擁塞控制」與「流量控制」的區別
擁塞控制就是防止過多的數據注入到網絡中,使網絡中的路由器或鏈路不致過載;而流量控制每每指點對點通訊量的控制,是個端到端的問題(接收端控制發送端)。
擁塞控制是一個全局性的過程,涉及到全部的主機、全部的路由器,以及與下降網絡傳輸性能有關的全部因素。
流量控制所要作的就是抑制發送端發送數據的速率,以便使接收端來得及接收。htm
TCP採用基於窗口的方法進行擁塞控制。
TCP發送方維持一個「擁塞窗口」(congestion window),以控制端到端之間未確認的報文數量(擁塞的程度)。blog
這和以前提到的用於流量控制的「滑動窗口」很像,可是和由接受方決定的「滑動窗口」大小不一樣,「擁塞窗口」的大小是由發送方決定的。
發送窗口大小不只取決於接收方公告的接收窗口,還取決於網絡的擁塞情況。
真正的發送窗口值爲:Min(公告窗口值,擁塞窗口值)
一、重傳定時器超時
因爲因傳輸出差錯而丟棄分組的機率是很小的(遠小於1%),因此只要出現了超時,就能夠猜測網絡可能出現了擁塞。
二、收到三個相同的ACK(3 duplicate ACKs)
先假設這麼一種狀況,B等待A發送首字節序號爲3的報文段,給A發送「ack = 3」的確認報文段(ACK),而A在發送過程當中出現了丟失,B收到的只有四、5字節的報文段;
此時B給A發送的確認報文中ack字段仍然等於3(由於字節3還沒收到);
接着,在B收到字節6後,給A發送的確認報文仍然是「ack = 3」
這就是「收到三個相同ACK」的場景。
所以咱們知道,「收到三個相同的ACK」說明有個別報文段在網絡中丟失了,預示着網絡情況很差,可能會出現擁塞,須要採起措施避免擁塞。
擁塞控制是個麻煩事兒,相關的算法也很多。或者說,多到讓人有些頭大。
不過不用擔憂,咱們這裏只介紹在RFC 5681文件中定義的四種互相緊密關聯的算法:
下面的這張圖是一個擁塞控制的過程示例,在學習每個部分的時候,能夠對應圖中相應的部分理解。
雖然叫「慢開始」,可是它的擁塞窗口(cwnd)增加的速度可一點也不「慢」。
使用慢開始算法後,每收到一個ACK,窗口值就加一;也就是意味着,每通過一個往返時間RTT,擁塞窗口cwnd就加倍。
這裏的一個「往返時間」指把擁塞窗口 cwnd 所容許發送的報文段都連續發送出去,並收到了對已發送的最後一個字節的確認。
慢開始門限至關於慢開始「指數式增加」的一個閾值。
擁塞避免的設計思路是讓擁塞窗口的增加「慢下來」(相對於慢開始),呈線性增加,或者叫「加法增大」(Additive Increase)。
當發現網絡出現擁塞時(重傳定時器超時),進行如下操做:
就是發送方一連收到 3 個對同一個報文段的重複確認(3-ACK)時,發送方執行快重傳和快恢復算法。
快重傳(Fast Retransmission)
發送方只要一連收到三個重複確認,就知道接收方確實沒有收到報文段,於是當即進行重傳(即「快重傳」),這樣就不會出現超時,發送方也不就會誤認爲出現了網絡擁塞。
快重傳並不是取消重傳計時器,而是在某些狀況下可更早地重傳丟失的報文段。
快恢復(Fast Recovery)
執行擁塞避免算法
能夠留意一下「快恢復」與發現網絡出現擁塞時(重傳定時器超時)的「‘慢’恢復」的區別。
兩者的結合就是所謂的AIMD算法。
【後記】
擁塞控制的算法這裏只介紹了較爲經常使用的4種,更詳細的內容維基百科--TCP congestion control講得也比較清楚。 接下來的兩週可能會比較忙,沒有辦法更新博客了。最近對3B1B的動畫引擎比較感興趣,可能會寫一些相關的內容。 最後,每一條留言都是個人動力(提早祝你們聖誕快樂了