動(dòng)畫:如何給面試官回答 TCP 的擁塞控制?
前邊我們分享了網(wǎng)絡(luò)分層協(xié)議、TCP 三次握手、TCP 四次分手。今天我們繼續(xù)深入分享一下 TCP 中的擁塞控制。
對(duì)于 TCP 的擁塞控制,里邊設(shè)計(jì)到很多細(xì)節(jié),小鹿希望通過這一節(jié)能夠?qū)⑦@部分內(nèi)容串通起來,能夠讓你更深刻的記憶這部分內(nèi)容。
思維導(dǎo)圖
1. 什么是擁塞控制?
擁塞控制是一種用來調(diào)整傳輸控制協(xié)議(TCP)連接單次發(fā)送的分組數(shù)量的算法。它通過增減單次發(fā)送量逐步調(diào)整,使之逼近當(dāng)前網(wǎng)絡(luò)的承載量。
簡單易懂的話來說,所謂的擁塞控制,從字面的意思來講,網(wǎng)絡(luò)通信就像是一個(gè)水管里的水,如果水突然因?yàn)樗艿内E物阻塞了,那么我們就應(yīng)該采取一定的策略,讓其在阻塞的時(shí)候如何處理。
2. 為什么進(jìn)行擁塞控制?
如果發(fā)送端要給接收端發(fā)送數(shù)據(jù),只有當(dāng)接收端接收到數(shù)據(jù)時(shí),才會(huì)給發(fā)送端返回應(yīng)答信息。如果接收端沒有發(fā)送應(yīng)答信息,發(fā)送端則認(rèn)為該數(shù)據(jù)已經(jīng)丟失,則進(jìn)行重新發(fā)送。

其實(shí)我們也不知道接收端有沒有接收,數(shù)據(jù)包到底在哪一步出現(xiàn)了問題呢?分為兩種情況,如下:
1. 數(shù)據(jù)包真的在半路丟失了

2. 網(wǎng)絡(luò)通信處于擁擠狀態(tài),數(shù)據(jù)包還沒有到達(dá)接收方。

我們的擁塞控制是主要針對(duì)于第二種情況的。如果網(wǎng)絡(luò)信道中一直處于擁擠狀態(tài),那么發(fā)送端一直進(jìn)行發(fā)送,就會(huì)變得更加的阻塞,而且同時(shí)白白浪費(fèi)掉了網(wǎng)絡(luò)的資源。
3. 測試網(wǎng)絡(luò)狀況
我們進(jìn)行擁塞控制之前,首先要判斷網(wǎng)絡(luò)信道是否阻塞了,當(dāng)判斷出網(wǎng)絡(luò)阻塞時(shí),我們才能進(jìn)行擁塞控制。我們一般通過向網(wǎng)絡(luò)中連續(xù)發(fā)送多個(gè)數(shù)據(jù)包來進(jìn)行測試,測試過程中,如果發(fā)送數(shù)據(jù)包到達(dá)了一定的程度,網(wǎng)絡(luò)通信就會(huì)阻塞。
有以下兩種探測網(wǎng)絡(luò)的情況,第一種就是逐漸遞增發(fā)送數(shù)據(jù)包,一次只發(fā)送一個(gè)數(shù)據(jù)包,第二次發(fā)送兩個(gè),第三次發(fā)送三個(gè),以此類推,總會(huì)在一個(gè)點(diǎn)發(fā)送網(wǎng)絡(luò)擁堵情況
第二種情況就是指數(shù)型的增長,顧名思義,就是發(fā)送數(shù)據(jù)包以指數(shù)的形式進(jìn)行增長,第一次發(fā)生一個(gè),第二次發(fā)送兩個(gè),第三次發(fā)送四個(gè)...也會(huì)在某一時(shí)刻網(wǎng)絡(luò)進(jìn)行擁堵。
但是第一種方法有一個(gè)問題就是增長的太慢,當(dāng)?shù)竭_(dá)到擁塞時(shí),需要經(jīng)歷很長的時(shí)間,這種探測的方式效率太低。
當(dāng)我們使用第二種方法時(shí),指數(shù)增長就會(huì)出現(xiàn)增長的太快,會(huì)錯(cuò)過增長的點(diǎn)。
既然兩種方式各有所長,我們就結(jié)合兩種方式,首先我們進(jìn)行指數(shù)增長,我們?cè)O(shè)定一定的閥值,然后到達(dá)閥值之后,然后進(jìn)行逐次遞增,直到出現(xiàn)網(wǎng)絡(luò)擁塞為止。
- 指數(shù)增長階段稱為慢啟動(dòng)
- 逐次增長稱之為擁塞避免
4. 什么是擁塞窗口?
我們把一次性能夠發(fā)送的數(shù)據(jù)包多少的窗口稱之為擁塞窗口。
我們通過控制發(fā)送窗口的大小,也就是發(fā)送數(shù)據(jù)包的多少來進(jìn)行擁塞控制。
5. 阻塞超時(shí)
當(dāng)數(shù)據(jù)包增長到一定程度就會(huì)出現(xiàn)超時(shí)事件(阻塞),出現(xiàn)超時(shí)事件就認(rèn)為網(wǎng)絡(luò)擁塞了,不能再繼續(xù)增長了,此時(shí)標(biāo)記為一個(gè)最大值 M。
如果超時(shí)了之后,我們開始進(jìn)行擁塞控制,怎么做呢?我們將增長的閥值進(jìn)行降低,降低到 M 的一半大小,也就是 M/2。如下圖所示,最大值為 24,此時(shí)發(fā)生擁塞,所以將閥值降為 12。
有的小伙伴就說了,你那超時(shí)不一定發(fā)生阻塞了,上邊你也提到了,可能出現(xiàn)了數(shù)據(jù)包的丟失,那怎么判斷這種情況呢?
6. 判斷發(fā)送超時(shí)的情況
我們上邊也說了,超時(shí)存在兩種情況,我們就采用連續(xù)發(fā)送 ACK 的方式來進(jìn)行判斷到底是網(wǎng)絡(luò)阻塞了還是網(wǎng)絡(luò)數(shù)據(jù)包丟失了。
如下圖所示,如果發(fā)送一個(gè)數(shù)據(jù)包,接收端成功接收之后,就會(huì)返回一個(gè)響應(yīng)數(shù)據(jù)包,然后發(fā)送端再次發(fā)送下一個(gè)數(shù)據(jù)包。
一旦發(fā)送端在發(fā)送數(shù)據(jù)包的時(shí)候中途丟失了,接收端會(huì)返回上一次接收的數(shù)據(jù)包的確認(rèn)響應(yīng)數(shù)據(jù)包,當(dāng)發(fā)送端連續(xù)接收到三個(gè)相同的響應(yīng)數(shù)據(jù)包時(shí),就說明該數(shù)據(jù)包丟失了,然后快速重傳該數(shù)據(jù)包。
然后會(huì)把我們的閥值設(shè)置為擁塞最大值 M 的一半,這時(shí)候的擁塞窗口的大小為 1,當(dāng)擁塞窗口的大小等于閥值時(shí),再進(jìn)行線性增長。我們也把上邊這種情況稱之為快速恢復(fù)。
小結(jié)
今天主要分享了 TCP 的擁塞控制,為什么會(huì)有擁塞控制?如何進(jìn)行擁塞控制以及如何判斷網(wǎng)絡(luò)中的情況。
通過擁塞控制,我們能夠更好地進(jìn)行數(shù)據(jù)高效的傳輸,除此之外,我們后邊的文章還會(huì)更新 TCP 的流量控制,為了能夠使得網(wǎng)絡(luò)中的流量得到充分的利用。