1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        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ī)制一般是用來(lái)解決數(shù)據(jù)包在錯(cuò)綜復(fù)雜的網(wǎng)絡(luò)中丟失的情況。


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

        超時(shí)重傳

        快速重傳

        SACK

        D-SACK


        超時(shí)重傳


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


        當(dāng)超過(guò)指定的時(shí)間后,沒(méi)有收到對(duì)方的 ACK 確認(rèn)應(yīng)答報(bào)文,就會(huì)重發(fā)該數(shù)據(jù),也就是我們常說(shuō)的超時(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í),就說(shuō)明網(wǎng)絡(luò)環(huán)境差,不宜頻繁反復(fù)發(fā)送。


        快速重傳


        快速重傳

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




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


        為了解決不知道該重傳哪些 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ù)沒(méi)收到,知道了這些信息,就可以只重傳丟失的數(shù)據(jù)


        Duplicate SACK


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


        滑動(dòng)窗口


        滑動(dòng)窗口是為了提升通信效率在操作系統(tǒng)開(kāi)辟的一個(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ā)送速率,保證接收方來(lái)得及接收。


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


        接收方發(fā)送的確認(rèn)報(bào)文中的window字段可以用來(lái)控制發(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è)接收端的處理能力來(lái)發(fā)送數(shù)據(jù),而不會(huì)導(dǎo)致接收端處理不過(guò)來(lái)。接收窗口的大小是約等于發(fā)送窗口的大小。


        窗口大小


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


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


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


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


        這其實(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ā)送但總大小超過(guò)接收方處理范圍(接收方?jīng)]有空間):52字節(jié)以后


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

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

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

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

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

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

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


        發(fā)送窗口




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

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

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

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


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

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

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


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

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

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


        擁塞控制


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

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

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

        如果網(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)不同。


        流量控制是為了讓接收方能來(lái)得及接收,而擁塞控制是為了降低整個(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ò)中沒(méi)有出現(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ù)增長(zhǎng)變成了線性增長(zhǎng),還是增長(zhǎng)階段,但是增長(zhǎng)速度緩慢了一些。


        就這么一直增長(zhǎng)著后,網(wǎng)絡(luò)就會(huì)慢慢進(jìn)入了擁塞的狀況了,于是就會(huì)出現(xiàn)丟包現(xiàn)象,這時(shí)就需要對(duì)丟失的數(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)的信號(hào)。


        對(duì)于丟包有兩種判定方式:

        超時(shí)重傳

        快速重傳


        超時(shí)重傳:是TCP協(xié)議保證數(shù)據(jù)可靠性的一個(gè)重要機(jī)制,其原理是在發(fā)送一個(gè)數(shù)據(jù)以后就開(kāi)啟一個(gè)計(jì)時(shí)器,在一定時(shí)間內(nèi)如果沒(mé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)過(guò)程


        快速重傳:當(dāng)發(fā)送端接收到3個(gè)以上的重復(fù)ACK,TCP就意識(shí)到數(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 說(shuō)明網(wǎng)絡(luò)也不那么糟糕,所以沒(méi)有必要像 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ù),說(shuō)明從 duplicated ACK 時(shí)的數(shù)據(jù)都已收到,該恢復(fù)過(guò)程已經(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)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

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

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            最新一级片 | 色偷偷色噜噜狠狠成人免费 | 中文字幕免费MV第一季歌词 | 骚日韩 | 男人天堂新网址 | 精产国品少妇在线视频 | 免费看插逼 | 黄色免费视频 | 日本日逼网站 | 又肉又嫩的骚淫视频 |