<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          TCP重傳與擁塞控制機(jī)制一覽

          共 3926字,需瀏覽 8分鐘

           ·

          2022-11-01 17:16

          目錄

          • 重傳機(jī)制

          • 超時(shí)重傳

          • 快速重傳

          • SACK 方法

          • Duplicate SACK

          • 滑動(dòng)窗口

          • 窗口大小

          • 接收窗口

          • 發(fā)送窗口

          • 擁塞控制

          • 慢啟動(dòng)

          • 擁塞避免

          • 擁塞發(fā)生

          • 為何快速重傳是選擇3次ACK?

          • 快速恢復(fù)

          重傳機(jī)制


          重傳機(jī)制一般是用來解決數(shù)據(jù)包在錯(cuò)綜復(fù)雜的網(wǎng)絡(luò)中丟失的情況。


          常見的重傳機(jī)制:

          超時(shí)重傳

          快速重傳

          SACK

          D-SACK


          超時(shí)重傳


          重傳機(jī)制的其中一個(gè)方式,就是在發(fā)送數(shù)據(jù)時(shí),設(shè)定一個(gè)定時(shí)器。


          當(dāng)超過指定的時(shí)間后,沒有收到對方的 ACK 確認(rèn)應(yīng)答報(bào)文,就會(huì)重發(fā)該數(shù)據(jù),也就是我們常說的超時(shí)重傳


          TCP 會(huì)在以下兩種情況發(fā)生超時(shí)重傳:

          數(shù)據(jù)包丟失

          確認(rèn)應(yīng)答丟失



          超時(shí)時(shí)間應(yīng)該設(shè)置為多少呢?

          超時(shí)重傳時(shí)間 RTO 的值應(yīng)該略大于報(bào)文往返 RTT 的值


          RTT 指的是數(shù)據(jù)發(fā)送時(shí)刻到接收到確認(rèn)的時(shí)刻的差值,也就是包的往返時(shí)間。


          超時(shí)重傳時(shí)間是以 RTO (Retransmission Timeout 超時(shí)重傳時(shí)間)表示。





          如果超時(shí)重發(fā)的數(shù)據(jù),再次超時(shí)的時(shí)候,又需要重傳的時(shí)候,TCP 的策略是超時(shí)間隔加倍。


          也就是每當(dāng)遇到一次超時(shí)重傳的時(shí)候,都會(huì)將下一次超時(shí)時(shí)間間隔設(shè)為先前值的兩倍。兩次超時(shí),就說明網(wǎng)絡(luò)環(huán)境差,不宜頻繁反復(fù)發(fā)送。


          快速重傳


          快速重傳

          TCP 還有另外一種快速重傳(Fast Retransmit)機(jī)制,它不以時(shí)間為驅(qū)動(dòng),而是以數(shù)據(jù)驅(qū)動(dòng)重傳。




          快速重傳機(jī)制只解決了一個(gè)問題,就是超時(shí)時(shí)間的問題,但是它依然面臨著另外一個(gè)問題。就是重傳的時(shí)候,是重傳之前的一個(gè),還是重傳所有的問題。


          為了解決不知道該重傳哪些 TCP 報(bào)文,于是就有 SACK 方法。


          SACK 方法


          還有一種實(shí)現(xiàn)重傳機(jī)制的方式叫:SACK( Selective Acknowledgment 選擇性確認(rèn))。


          這種方式需要在 TCP 頭部「選項(xiàng)」字段里加一個(gè) SACK 的東西,它可以將緩存的地圖發(fā)送給發(fā)送方,這樣發(fā)送方就可以知道哪些數(shù)據(jù)收到了,哪些數(shù)據(jù)沒收到,知道了這些信息,就可以只重傳丟失的數(shù)據(jù)。


          Duplicate SACK


          Duplicate SACK 又稱 D-SACK,其主要使用了 SACK 來告訴「發(fā)送方」有哪些數(shù)據(jù)被重復(fù)接收了。


          滑動(dòng)窗口


          滑動(dòng)窗口是為了提升通信效率在操作系統(tǒng)開辟的一個(gè)緩存空間,發(fā)送方主機(jī)在等到確認(rèn)應(yīng)答返回之前,必須在緩沖區(qū)中保留已發(fā)送的數(shù)據(jù)。如果按期收到確認(rèn)應(yīng)答,此時(shí)數(shù)據(jù)就可以從緩存區(qū)清除。


          TCP 利用滑動(dòng)窗口實(shí)現(xiàn)流量控制。流量控制是為了控制發(fā)送方發(fā)送速率,保證接收方來得及接收。


          TCP會(huì)話的雙方都各自維護(hù)一個(gè)發(fā)送窗口和一個(gè)接收窗口。接收窗口大小取決于應(yīng)用、系統(tǒng)、硬件的限制。發(fā)送窗口則取決于對端通告的接收窗口。


          接收方發(fā)送的確認(rèn)報(bào)文中的window字段可以用來控制發(fā)送方窗口大小,從而影響發(fā)送方的發(fā)送速率。將接收方的確認(rèn)報(bào)文window字段設(shè)置為 0,則發(fā)送方不能發(fā)送數(shù)據(jù)。


          TCP頭包含window字段,16bit位,它代表的是窗口的字節(jié)容量,最大為65535。這個(gè)字段是接收端告訴發(fā)送端自己還有多少緩沖區(qū)可以接收數(shù)據(jù)。于是發(fā)送端就可以根據(jù)這個(gè)接收端的處理能力來發(fā)送數(shù)據(jù),而不會(huì)導(dǎo)致接收端處理不過來。接收窗口的大小是約等于發(fā)送窗口的大小。


          窗口大小


          窗口大小由哪一方?jīng)Q定?


          TCP 頭里有一個(gè)字段叫 Window,也就是窗口大小。


          這個(gè)字段是接收方告訴發(fā)送端子機(jī)還有多少緩沖區(qū)可以接收數(shù)據(jù)的。


          發(fā)送端會(huì)根據(jù)反饋回來的信息發(fā)送數(shù)據(jù),這樣就可以保證不會(huì)出現(xiàn)接收端處理不過來的情況。


          這其實(shí)就是流量控制。


          流量控制是TCP 提供的一種可以讓「發(fā)送方」根據(jù)「接收方」的實(shí)際接收能力控制發(fā)送的數(shù)據(jù)量的一種機(jī)制。


          接收窗口



          #1 是已發(fā)送并收到 ACK確認(rèn)的數(shù)據(jù):1~31 字節(jié)

          #2 是已發(fā)送但未收到 ACK確認(rèn)的數(shù)據(jù):32~45 字節(jié)

          #3 是未發(fā)送但總大小在接收方處理范圍內(nèi)(接收方還有空間):46~51字節(jié)

          #4 是未發(fā)送但總大小超過接收方處理范圍(接收方?jīng)]有空間):52字節(jié)以后


          程序是如何表示發(fā)送方的四個(gè)部分的呢?

          TCP 滑動(dòng)窗口方案使用三個(gè)指針來跟蹤在四個(gè)傳輸類別中的每一個(gè)類別中的字節(jié)。

          其中兩個(gè)指針是絕對指針(指特定的序列號),一個(gè)是相對指針(需要做偏移)。

          SND.WND:表示發(fā)送窗口的大?。ù笮∈怯山邮辗街付ǖ模?;

          SND.UNA(Send Unacknoleged):是一個(gè)絕對指針,它指向的是已發(fā)送但未收到確認(rèn)的第一個(gè)字節(jié)的序列號,也就是 #2 的第一個(gè)字節(jié)。

          SND.NXT:也是一個(gè)絕對指針,它指向未發(fā)送但可發(fā)送范圍的第一個(gè)字節(jié)的序列號,也就是 #3 的第一個(gè)字節(jié)。

          指向 #4 的第一個(gè)字節(jié)是個(gè)相對指針,它需要 SND.UNA 指針加上 SND.WND 大小的偏移量,就可以指向 #4 的第一個(gè)字節(jié)了。


          發(fā)送窗口




          #1 + #2 是已成功接收并確認(rèn)的數(shù)據(jù)(等待應(yīng)用進(jìn)程讀?。?;

          #3 是未收到數(shù)據(jù)但可以接收的數(shù)據(jù);

          #4 未收到數(shù)據(jù)并不可以接收的數(shù)據(jù);

          其中三個(gè)接收部分,使用兩個(gè)指針進(jìn)行劃分:


          RCV.WND:表示接收窗口的大小,它會(huì)通告給發(fā)送方。

          RCV.NXT:是一個(gè)指針,它指向期望從發(fā)送方發(fā)送來的下一個(gè)數(shù)據(jù)字節(jié)的序列號,也就是 #3 的第一個(gè)字節(jié)。

          指向 #4 的第一個(gè)字節(jié)是個(gè)相對指針,它需要 RCV.NXT 指針加上 RCV.WND 大小的偏移量,就可以指向 #4 的第一個(gè)字節(jié)了。


          接收窗口和發(fā)送窗口的大小是相等的嗎?

          并不是完全相等,接收窗口的大小是約等于發(fā)送窗口的大小的。

          因?yàn)榻邮沾翱诘拇笮∈怯?TCP報(bào)文中的 Windows 字段來告訴發(fā)送方的,而這個(gè)傳輸過程是存在實(shí)驗(yàn)的,所以接收窗口和發(fā)送窗口是約等于的關(guān)系。


          擁塞控制


          為什么要有擁塞控制呀,不是有流量控制了嗎?

          流量控制確實(shí)避免了「發(fā)送方」的數(shù)據(jù)填滿「接收方」的緩存,但是機(jī)制并不知道網(wǎng)絡(luò)的中發(fā)生了什么。

          網(wǎng)絡(luò)中對資源需求超過了資源可用量的情況就叫做擁塞。

          如果網(wǎng)絡(luò)出現(xiàn)擁塞,分組將會(huì)丟失,此時(shí)發(fā)送方會(huì)繼續(xù)重傳,從而導(dǎo)致網(wǎng)絡(luò)擁塞程度更高。因此當(dāng)出現(xiàn)擁塞時(shí),應(yīng)當(dāng)控制發(fā)送方的速率。這一點(diǎn)和流量控制很像,但是出發(fā)點(diǎn)不同。


          流量控制是為了讓接收方能來得及接收,而擁塞控制是為了降低整個(gè)網(wǎng)絡(luò)的擁塞程度。


          擁塞控制主要是四個(gè)算法:

          慢啟動(dòng)

          擁塞避免

          擁塞發(fā)生

          快速恢復(fù)


          擁塞窗口:為了調(diào)節(jié)發(fā)送方所要發(fā)送數(shù)據(jù)的量而引入的概念


          發(fā)送窗口 swnd 和接收窗口 rwnd 是約等于的關(guān)系


          加入了擁塞窗口的概念后,此時(shí)發(fā)送窗口的值是swnd = min(cwnd, rwnd),


          擁塞窗口 cwnd 變化的規(guī)則:

          只要網(wǎng)絡(luò)中沒有出現(xiàn)擁塞,cwnd 就會(huì)增大;

          但網(wǎng)絡(luò)中出現(xiàn)了擁塞,cwnd 就減少;


          慢啟動(dòng)


          機(jī)制含義:TCP 在剛建立連接完成后,緩慢提高發(fā)送數(shù)據(jù)包的數(shù)量


          算法機(jī)制:當(dāng)發(fā)送方每收到一個(gè) ACK,擁塞窗口 cwnd 的大小就會(huì)加 1。


          有一個(gè)叫慢啟動(dòng)門限 ssthresh (slow start threshold)狀態(tài)變量。


          當(dāng) cwnd < ssthresh 時(shí),使用慢啟動(dòng)算法。

          當(dāng) cwnd >= ssthresh 時(shí),就會(huì)使用「擁塞避免算法」。


          擁塞避免


          算法機(jī)制:每當(dāng)收到一個(gè) ACK 時(shí),cwnd 增加 1/cwnd。



          如圖,擁塞避免算法就是將原本慢啟動(dòng)算法的指數(shù)增長變成了線性增長,還是增長階段,但是增長速度緩慢了一些。


          就這么一直增長著后,網(wǎng)絡(luò)就會(huì)慢慢進(jìn)入了擁塞的狀況了,于是就會(huì)出現(xiàn)丟包現(xiàn)象,這時(shí)就需要對丟失的數(shù)據(jù)包進(jìn)行重傳。


          當(dāng)觸發(fā)了重傳機(jī)制,也就進(jìn)入了「擁塞發(fā)生算法」。


          擁塞發(fā)生


          TCP擁塞控制默認(rèn)認(rèn)為網(wǎng)絡(luò)丟包是由于網(wǎng)絡(luò)擁塞導(dǎo)致的,,所以一般的TCP擁塞控制算法以丟包為網(wǎng)絡(luò)進(jìn)入擁塞狀態(tài)的信號。


          對于丟包有兩種判定方式:

          超時(shí)重傳

          快速重傳


          超時(shí)重傳:是TCP協(xié)議保證數(shù)據(jù)可靠性的一個(gè)重要機(jī)制,其原理是在發(fā)送一個(gè)數(shù)據(jù)以后就開啟一個(gè)計(jì)時(shí)器,在一定時(shí)間內(nèi)如果沒有得到發(fā)送數(shù)據(jù)報(bào)的ACK報(bào)文,那么就重新發(fā)送數(shù)據(jù),直到發(fā)送成功為止。


          當(dāng) RTO超時(shí)后,TCP會(huì)重傳 數(shù)據(jù)包并做出以下反映。


          將慢啟動(dòng)的閾值設(shè)置為 當(dāng)前 cwnd 的一半

          cwnd 重置為一

          進(jìn)入慢啟動(dòng)過程


          快速重傳:當(dāng)發(fā)送端接收到3個(gè)以上的重復(fù)ACK,TCP就意識到數(shù)據(jù)發(fā)生丟失,需要快速重傳。


          快速重傳后不會(huì)使用慢啟動(dòng)算法,而是直接使用擁塞避免算法。所以也叫快速恢復(fù)算法Fast Recovery。


          cwnd大小縮小為當(dāng)前的一半

          將慢啟動(dòng)的閾值設(shè)置為為縮小后的cwnd大小

          然后進(jìn)入快速恢復(fù)算法Fast Recovery。


          為何快速重傳是選擇3次ACK?

          兩次duplicated ACK時(shí)很可能是亂序造成的!三次duplicated ACK時(shí)很可能是丟包造成的!四次duplicated ACK更更更可能是丟包造成的,但是這樣的響應(yīng)策略太慢。丟包肯定會(huì)造成三次duplicated ACK!綜上是選擇收到三個(gè)重復(fù)確認(rèn)時(shí)窗口減半效果最好,這是實(shí)踐經(jīng)驗(yàn)。


          快速恢復(fù)


          快速重傳和快速恢復(fù)算法一般同時(shí)使用,快速恢復(fù)算法是認(rèn)為,你還能收到 3 個(gè)重復(fù) ACK 說明網(wǎng)絡(luò)也不那么糟糕,所以沒有必要像 RTO 超時(shí)那么強(qiáng)烈。


          然后,進(jìn)入快速恢復(fù)算法如下:


          擁塞窗口 cwnd = ssthresh + 3 ( 3 的意思是確認(rèn)有 3 個(gè)數(shù)據(jù)包被收到了);

          重傳丟失的數(shù)據(jù)包;

          如果再收到重復(fù)的 ACK,那么 cwnd 增加 1;

          如果收到新數(shù)據(jù)的 ACK 后,把 cwnd 設(shè)置為第一步中的 ssthresh 的值,原因是該 ACK 確認(rèn)了新的數(shù)據(jù),說明從 duplicated ACK 時(shí)的數(shù)據(jù)都已收到,該恢復(fù)過程已經(jīng)結(jié)束,可以回到恢復(fù)之前的狀態(tài)了,也即再次進(jìn)入擁塞避免狀態(tài);



          關(guān)于TCP的總結(jié)就到這里啦,你弄懂了嗎?

          本文節(jié)選自:小林coding

          Linux學(xué)習(xí)指南

          有收獲,點(diǎn)個(gè)在看 

          瀏覽 24
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天干夜夜爽 | 精品国产一区二 | 啪啪啪啪啪啪AVXXX | 岛国免费播放器无码 | 奇米影视狠狠去 |