成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

網(wǎng)絡協(xié)議 9 - TCP(下)

Noodles / 3265人閱讀

摘要:收到了,發(fā)送,要求下一個是,不幸又丟了。在對于包的確認中,會同時攜帶一個窗口大小的字段。前面的滑動窗口是怕發(fā)送方把接收方緩存塞滿,而擁塞窗口,是怕把網(wǎng)絡塞滿。這里有一個公式可以看出,是擁塞窗口和滑動窗口共同控制發(fā)送的速度。

網(wǎng)絡協(xié)議 1 - 概述

網(wǎng)絡協(xié)議 2 - IP 是怎么來,又是怎么沒的?

網(wǎng)絡協(xié)議 3 - 從物理層到 MAC 層

網(wǎng)絡協(xié)議 4 - 交換機與 VLAN:辦公室太復雜,我要回學校

網(wǎng)絡協(xié)議 5 - ICMP 與 ping:投石問路的偵察兵

網(wǎng)絡協(xié)議 6 - 路由協(xié)議:敢問路在何方?

網(wǎng)絡協(xié)議 7 - UDP 協(xié)議:性善碰到城會玩

網(wǎng)絡協(xié)議 8 - TCP 協(xié)議(上):性惡就要套路深


????上次了解了 TCP 建立連接與斷開連接的過程,我們發(fā)現(xiàn),TCP 會通過各種“套路”來保證傳輸數(shù)據(jù)的安全。除此之外,我們還大概了解了 TCP 包頭格式所對應解決的五個問題:順序問題、丟包問題、連接維護、流量控制、擁塞控制。今天,我們就來看下 TCP 又是用怎樣的套路去解決這五個問題的。

????在解決問題之前,咱們先來看看 TCP 是怎么成為一個“靠譜”的協(xié)議的。

“靠譜”協(xié)議 TCP

????TCP 為了保證順序性,每個包都有一個 ID。這建立連接的時候,會商定起始 ID 的值,然后按照 ID一個個發(fā)送。

????為了保證不丟包,對于發(fā)送的包都要進行應答。但是這個應答不是一個一個來的,而是會應答某個之前的 ID,表示都收到了,這種模式稱為累計確認累計應答。

為了記錄所有發(fā)送的包和接收的包,TCP 也需要發(fā)送端和接收端分別用緩存來保存這些記錄。發(fā)送端的緩存里是按照包的 ID 一個個排列,根據(jù)處理的情況分成四個部分:

第一部分:發(fā)送且已經(jīng)確認的;

第二部分:發(fā)送尚未確認的;

第三部分:沒有發(fā)送,但是已經(jīng)等待發(fā)送的;

第四部分:沒有發(fā)送,并且暫時還不會發(fā)送的。

????于是,發(fā)送端需要保持這樣的數(shù)據(jù)結(jié)構(gòu):

LastByteAcked:第一部分和第二部分的分界線

LastByteSent:第二部分和第三部分的分界線

LastByteAcked:第三部分和第四部分的分界線

對于接收端來講,它緩存記錄的內(nèi)容要簡單一些,分為以下三個部分:

第一部分:接收且確認過的;

第二部分:還沒接收,但是馬上就能接收的;

第三部分:還沒接收,也沒空間接收的。

????對應的數(shù)據(jù)結(jié)構(gòu)就像這樣:

MaxRcvBuffer:最大緩存量;

LastByteRead:這個值之后是已經(jīng)接收,但是還沒被應用層讀取的;

NextByteExpected:第一部分和第二部分的分界線,下一個期待的包 ID。

????第二部分的窗口有多大呢?

????NextByteExpected 和 LastByteRead 的差起始是還沒被應用層讀取的部分占用掉的 MaxRcvBuffer 的量,我們定義為 A,即:A = NextByteExpected - LastByteRead - 1。

????那么,窗口大小,AdvertisedWindow = MaxRcvBuffer - A。

????也就是:AdvertisedWindow = MaxRcvBuffer - (NextByteExpected - LastByteRead - 1)

????而第二部分和三部分的分界線 = NextByteExpected + AdvertisedWindow - 1 = MaxRcvBuffer + LastByteRead。

順序與丟包問題

????接下來,我們結(jié)合上述圖例,用一個例子來看下 TCP 如何處理順序與丟包問題的。

還是剛才的圖,在發(fā)送端看來:

1、2、3 是已經(jīng)發(fā)送并確認的;

4、5、6、7、8、9 都是發(fā)送未確認的;

10、11、12 是還沒發(fā)出的;

13、14、15 是接收方?jīng)]有空間,不準備發(fā)送的。

而在接收端看來:

1、2、3、4、5 是已經(jīng)完成 ACK,但還沒讀取的;

6、7 是等待接收的;

8、9 是已經(jīng)接收,但是沒有 ACK 的。

發(fā)送端和接收端當前的狀態(tài)如下:

1、2、3 沒有問題,雙方達成了一致;

4、5 接收方發(fā)送 ACK 了,但是發(fā)送方還沒收到,有可能丟了,有可能還在路上;

6、7、8、9 肯定都發(fā)了,但是 8、9 已經(jīng)到了,6、7還沒打,出現(xiàn)了亂序,于是在緩存中存儲,但是沒有返回 ACK。

????根據(jù)這個例子,我們可以知道,順序問題和丟包問題都有了能發(fā)送,所以我們先來看確認與重發(fā)的機制。
????假設 4 的確認到了,不幸的是,5 的 ACK 丟了,并且 6、7 的數(shù)據(jù)包也丟了,這時候會怎么處理呢?

????一種方法是超時重試,也就是對每一個發(fā)送了,但是沒有 ACK 的包,都有設一個定時器,一旦超過了一定的時間,就重新嘗試。這個超時時間不宜過短,時間必須大于往返時間 RTT,否則就會引起不必要的重傳也不宜過長,這樣超時時間變長,訪問就變慢了。

????估計往返時間,需要 TCP 通過采樣 RTT 的時間,然后進行加權(quán)平均,算出一個值,而且這個值還是要不斷變化的,因為網(wǎng)絡狀況不斷的變化。

????除了采樣 RTT,還要采樣 RTT 的波動范圍,計算出一個估計的超時時間。由于重傳時間是不斷變化的,我們稱為自適應重傳算法(Adaptive Retransmission Algorithm)。

????如果過一段時間,5、6、7 都超時了,就會重新發(fā)送。接收方發(fā)現(xiàn) 5 原來接收過,于是就丟棄5。收到了6,發(fā)送 ACK,要求下一個是 7,7 不幸又丟了。

????當 7 再次超時的時候,如果有需要重傳,TCP 的策略就是超時間隔加倍。每當遇到一次超時重傳的實時,都會將下一次超時時間間隔設置為先前值的兩倍。兩次超時,就說明網(wǎng)絡環(huán)境差,不宜頻繁發(fā)送。

????可以看出,超時重發(fā)存在的問題是,超時周期可能較長。那是不是可以有更快的方式呢?

????有一個可以快速重傳的機制。當接收方收到一個序號大于下一個所期望的報文段時,就檢測到了數(shù)據(jù)流中的一個間格,于是發(fā)送三個冗余的ACK,客戶端收到后,就在定時器過期之前,重傳丟失的報文段。

????例如,接收方發(fā)現(xiàn) 6、8、9 都已經(jīng)接收了,但是 7 沒來。于是發(fā)送三個 6 的 ACK,要求下一個是 7??蛻舳耸盏饺齻€,就會發(fā)現(xiàn) 7 的確丟了,不等超時,就馬上重發(fā)。

????除此之外,還有一種方式稱為 Selective Acknowledgment(SACK)。這種方式需要在 TCP 頭里加一個 SACK 的東西,可以將緩存的地圖發(fā)格發(fā)送方。例如發(fā)送 ACK6、SACK8、SACK9,有了地圖,發(fā)送方一下子就能看出來是 7 丟了,然后快速重發(fā)。

流量控制問題

????接下來,我們再來看看流量控制機制。在對于包的確認中,會同時攜帶一個窗口大小的字段。

????我們先假設窗口不變的情況,發(fā)送端窗口始終為 9。4 的確認來的時候,LastByteAcked 會右移一個,這個時候,第 13 個包就可以發(fā)送了。

????這個時候,假設發(fā)送端發(fā)送過猛,將第三部分中的 10、11、12、13 全部發(fā)送,之后就停止發(fā)送,則此時未發(fā)送可發(fā)送部分為 0。

????當對于包 5 的確認到達的時候,在客戶端相當于窗口再滑動了一格,這個時候,才可以有更多的包可以發(fā)送了,例如第 14 個包才可以發(fā)送。

????如果接收方處理的太慢,導致緩存中沒有空間了,可以通過確認信息修改窗口的大小,甚至可以設置為 0,則發(fā)送方將暫時停止發(fā)送。

????我們可以假設一個極端情況,接收端的應用一直不讀取緩存中的數(shù)據(jù),當數(shù)據(jù)包 6 確認后,窗口大小就不會再是 9,而是減少一個變?yōu)榱?8。

????為什么會變?yōu)?8?你看,下圖中,當 6 的確認消息到達發(fā)送端的時候,左邊的 LastByteAcked 右移一位,而右邊的未發(fā)送可發(fā)送區(qū)域因為已經(jīng)變?yōu)?0,因此左邊的 LastByteSend 沒有移動,因此,窗口大小就從 9 變成了 8。

????而如果接收端一直不處理數(shù)據(jù),則隨著確認的包越來越多,窗口越來越小,直到為 0。

????當這個窗口大小通過包 14 的確認到達發(fā)送端的時候,發(fā)送端的窗口也調(diào)整為 0,于是,發(fā)送端停止發(fā)送。

????當發(fā)生這樣的情況時,發(fā)送方會定時發(fā)送窗口探測數(shù)據(jù)包,看是否有機會調(diào)整窗口的大小。對于接收方來說,當接收比較慢的時候,要防止低能窗口綜合征,別空出一個字節(jié)就趕緊告訴發(fā)送方,結(jié)果又被填滿了??梢栽诖翱谔〉臅r候,不更新窗口大小,直到達到一定大小,或者緩沖區(qū)一半為空,才更新窗口大小。

????這就是我們常說的流量控制。

擁塞控制問題

????最后,我們來看一下?lián)砣刂频膯栴}。

????這個問題,也是靠窗口來解決的。前面的滑動窗口 rwnd 是怕發(fā)送方把接收方緩存塞滿,而擁塞窗口 cwnd,是怕把網(wǎng)絡塞滿。

這里有一個公式:

LastByteSent - LastByteAcked <= min{cwnd, rwnd}

????可以看出,是擁塞窗口和滑動窗口共同控制發(fā)送的速度。

????那發(fā)送方怎么判斷網(wǎng)絡是不是滿呢?這其實是個挺難的事情。因為對于 TCP 協(xié)議來講,它壓根不知道整個網(wǎng)絡路徑都會經(jīng)歷什么。TCP 發(fā)送包常被比喻為往一個水管里灌水,而 TCP 的擁塞控制就是在不堵塞、不丟包的情況下,盡量發(fā)揮帶寬。

????水管有粗細,網(wǎng)絡有帶寬,也就是每秒鐘能夠發(fā)送多少數(shù)據(jù);

水管有長度,端到端有時延。在理想情況下:

水管里的水量 = 水管粗細 x 水管長度

而對于網(wǎng)絡來講:

通道的容量 = 帶寬 x 往返延遲

????如果我們設置發(fā)送窗口,使得發(fā)送但未確認的包的數(shù)量為通道的容量,就能夠撐滿整個管道。

如上圖所示:

假設往返時間為 8s,去 4s,回 4s,每秒發(fā)送一個包,每個包 1024 byte。

????那么在 8s 后,就發(fā)出去了 8 個包。其中前 4 個包已經(jīng)到達接收端,但是 ACK 還沒有返回,不能算發(fā)送成功。而 5-8 后四個包還在路上,沒被接收。

這個時候,整個管道正好撐滿。在發(fā)送端,已發(fā)送未確認的為 8 個包,也就是:

帶寬 = 1024byte/s x 8s(來回時間)

????如果我們在這個基礎(chǔ)上再調(diào)大窗口,使得單位時間內(nèi)更多的包可以發(fā)送,會出現(xiàn)什么現(xiàn)象呢?

????原來發(fā)送一個包,從一端到另一端,假設一共經(jīng)過四個設備,每個設備處理一個包耗時 1s,所以到達另一端需要耗費 4s。如果發(fā)送的更加快速,則單位時間內(nèi),會有更多的包到達這些中間設備,這些設備還是只能每秒處理一個包的話,多出來的包就會被丟棄,這不是我們希望看到的。

????這個時候,我們可以想其他的辦法。例如,這四個設備本來每秒處理一個包,但是我們在這些設備上加緩存,處理不過來的就在隊列里面排著,這樣包就不會丟失,但是缺點也是顯而易見的,增加了時延。這個緩存的包,4s 肯定到達不了接收端,如果時延達到一定程度,就會超時,這也不是我們希望看到的。

????針對上述兩種現(xiàn)象:包丟失超時重傳。一旦出現(xiàn)了這些現(xiàn)象就說明,發(fā)送速度太快了,要慢一點。但是一開始,發(fā)送端怎么知道速度多快呢?怎么知道把窗口調(diào)整到合適大小呢?

????如果我們通過漏斗往瓶子里灌水,我們就知道,不能一桶水一下子全倒進去,肯定會溢出來。一開始要慢慢的倒,然后發(fā)現(xiàn)都能夠倒進去,就加快速度。這叫做慢啟動。

一個 TCP 連接開始

cwnd 設置為一個報文段,一次只能發(fā)送 1 個;

當收到這一個確認的時候,cwnd 加 1,于是一次能夠發(fā)送 2 個;

當這兩個包的確認到來的時候,每個確認的 cwnd 加 1,兩個確認 cwnd 加 2,于是一次能夠發(fā)送 4 個;

當這四個的確認到來的時候,每個確認 cwnd 加 1,四個確認 cwnd 加 4,于是一次能夠發(fā)送 8 個。

????從上面這個過程可以看出,這是指數(shù)性的增長

????但是漲到什么時候是個頭呢?一個值 ssthresh 為 65535 個字節(jié),當超過這個值的時候,就會將將增長速度降下來。

????此時,每收到一個確認后,cwnd 增加 1/cwnd。一次發(fā)送 8 個,當 8 個確認到來的時候,每個確認增加 1/8,8個確認一共增加 1,于是一次就能夠發(fā)送 9 個,變成了線性增長

????即使增長變成了線性增長,還是會出現(xiàn)“溢出”的情況,出現(xiàn)擁塞。這時候一般就會直接降低倒水的速度,等待溢出的水慢慢滲透下去。

????擁塞的一種變現(xiàn)形式是丟包,需要超時重傳。這個時候,將 ssthresh 設為 cwnd/2,將 cwnd 設為 1,重新開始慢啟動。也就是,一旦超時重傳,馬上“從零開始”。

????很明顯,這種方式太激進了,將一個高速的傳輸速度一下子停了下來,會造成網(wǎng)絡卡頓。

????前面有提過快速重傳算法。當接收端發(fā)現(xiàn)丟了一個中間包的時候,發(fā)送三次前一個包的 ACK,告訴發(fā)送端要趕緊給我發(fā)下一個包,別等超時再重傳。TCP 認為這種情況不嚴重,因為大部分沒丟,只丟了一小部分,cwnd 變?yōu)?cwnd/2,然后 sshthresh = cwnd。當三個包返回的時候,cwnd = sshthresh + 3。

????可以看出這種情況下降速沒有那么激進,cwnd 還是在一個比較高的值,呈線性增長。下圖是兩者的對比。

????就像前面說的一樣,正是這種知進退,使得時延在很重要的情況下,反而降低了速度。但是,我們仔細想一想,TCP 的擁塞控制主要用來避免的兩個現(xiàn)象都是有問題的。

????第一個問題是丟包。丟包并不一定表示通道滿了,也可能是管子本來就”漏水”。就像公網(wǎng)上帶寬不滿也會丟包,這個時候就認為擁塞,而降低發(fā)送速度其實是不對的。

????第二個問題是 TCP 的擁塞控制要等到將中間設備都填滿了,才發(fā)送丟包,從而降低速度。但其實,這時候降低速度已經(jīng)晚了,在將管道填滿后,不應該接著填,直到發(fā)生丟包才降速。

????為了優(yōu)化這兩個問題,后來就有了 TCP BBR 擁塞算法。它企圖找到一個平衡點,就是通過不斷的加快發(fā)送速度,將管道填滿,但是不要填滿中間設備的緩存,因為這樣時延會增加,在這個平衡點可以很好的達到高帶寬和低時延的平衡。

????下圖是 BBR 算法與普通 TCP 的對比:

小結(jié)

順序問題、丟包問題、流量控制都是通過滑動窗口來解決的。這就相當于領(lǐng)導和員工的備忘錄,布置過的工作要有編號,干完了有反饋,活不能派太多,也不能太少;

擁塞控制是通過擁塞窗口來解決的,相當于往管道里面倒水,快了容易溢出,慢了浪費帶寬,要摸著石頭過河,找到最優(yōu)值。

參考:

The TCP/IP Guide;

百度百科 - TCP詞條;

劉超 - 趣談網(wǎng)絡協(xié)議系列課;

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/29750.html

相關(guān)文章

  • 網(wǎng)絡協(xié)議 9 - TCP

    摘要:收到了,發(fā)送,要求下一個是,不幸又丟了。在對于包的確認中,會同時攜帶一個窗口大小的字段。前面的滑動窗口是怕發(fā)送方把接收方緩存塞滿,而擁塞窗口,是怕把網(wǎng)絡塞滿。這里有一個公式可以看出,是擁塞窗口和滑動窗口共同控制發(fā)送的速度。 網(wǎng)絡協(xié)議 1 - 概述 網(wǎng)絡協(xié)議 2 - IP 是怎么來,又是怎么沒的? 網(wǎng)絡協(xié)議 3 - 從物理層到 MAC 層 網(wǎng)絡協(xié)議 4 - 交換機與 VLAN:辦公室太...

    Carbs 評論0 收藏0
  • PTPIP協(xié)議中文版

    摘要:操作請求只能由啟動器設備發(fā)起事件被響應端設備用于把有關(guān)它狀態(tài)的改變通知啟動器設備。會話將在啟動器設備請求操作事務時被關(guān)閉,并且使用響應端設備發(fā)出的一個有效響應成功結(jié)束該請求。標準協(xié)議節(jié)斷開事件。 歡迎關(guān)注公眾號: nullobject 。文章首發(fā)在個人博客 https://www.nullobject.cn,公眾號nullobject同步更新。 PTP/IP (PTP over IP)...

    plus2047 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<