日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

图解TCPIP协议

發布時間:2023/12/9 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图解TCPIP协议 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • 本文原文鏈接通過兩個圖來梳理TCP-IP協議相關知識。TCP通信過程包括三個步驟:建立TCP連接通道,傳輸數據,斷開TCP連接通道。如圖1所示,給出了TCP通信過程的示意圖。

    圖1主要包括三部分:建立連接傳輸數據斷開連接

    建立TCP連接很簡單,通過三次握手便可建立連接。

    建立好連接后,開始傳輸數據。TCP數據傳輸牽涉到的概念很多:超時重傳快速重傳流量控制擁塞控制等等。

    斷開連接的過程也很簡單,通過四次握手完成斷開連接的過程。

    三次握手建立連接

    第一次握手:客戶端發送syn包(seq=x)到服務器,并進入SYN_SEND狀態,等待服務器確認;

    第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=x+1),同時自己也發送一個SYN包(seq=y),即SYN+ACK包,此時服務器進入SYN_RECV狀態;

    第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=y+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。

    握手過程中傳送的包里不包含數據,三次握手完畢后,客戶端與服務器才正式開始傳送數據。理想狀態下,TCP連接一旦建立,在通信雙方中的任何一方主動關閉連接之前,TCP 連接都將被一直保持下去。

    傳輸數據過程:

    超時重傳

    超時重傳機制用來保證TCP傳輸的可靠性。每次發送數據包時,發送的數據報都有seq號,接收端收到數據后,會回復ack進行確認,表示某一seq號數據已經收到。發送方在發送了某個seq包后,等待一段時間,如果沒有收到對應的ack回復,就會認為報文丟失,會重傳這個數據包。

    快速重傳

    接受數據一方發現有數據包丟掉了。就會發送ack報文告訴發送端重傳丟失的報文。如果發送端連續收到標號相同的ack包,則會觸發客戶端的快速重傳(不用等到超時計時器結束即可確認數據包已經丟失)。比較超時重傳和快速重傳,可以發現超時重傳是發送端在傻等超時,然后觸發重傳;而快速重傳則是接收端主動告訴發送端數據沒收到,然后觸發發送端重傳。

    流量控制

    這里主要說TCP滑動窗流量控制。TCP頭里有一個字段叫Window,又叫Advertised-Window,這個字段是接收端告訴發送端自己還有多少緩沖區可以接收數據。于是發送端就可以根據這個接收端的處理能力來發送數據,而不會導致接收端處理不過來。 滑動窗可以是提高TCP傳輸效率的一種機制。

    擁塞控制

    滑動窗用來做流量控制。流量控制只關注發送端和接受端自身的狀況,而沒有考慮整個網絡的通信情況。擁塞控制,則是基于整個網絡來考慮的。考慮一下這樣的場景:某一時刻網絡上的延時突然增加,那么,TCP對這個事做出的應對只有重傳數據,但是,重傳會導致網絡的負擔更重,于是會導致更大的延遲以及更多的丟包,于是,這個情況就會進入惡性循環被不斷地放大。試想一下,如果一個網絡內有成千上萬的TCP連接都這么行事,那么馬上就會形成“網絡風暴”,TCP這個協議就會拖垮整個網絡。為此,TCP引入了擁塞控制策略。擁塞策略算法主要包括:慢啟動擁塞避免擁塞發生快速恢復

    四次握手斷開連接

    第一次揮手:主動關閉方發送一個FIN,用來關閉主動方到被動關閉方的數據傳送,也就是主動關閉方告訴被動關閉方:我已經不會再給你發數據了(當然,在fin包之前發送出去的數據,如果沒有收到對應的ack確認報文,主動關閉方依然會重發這些數據),但此時主動關閉方還可以接受數據。

    第二次揮手:被動關閉方收到FIN包后,發送一個ACK給對方,確認序號為收到序號+1(與SYN相同,一個FIN占用一個序號)。

    第三次揮手:被動關閉方發送一個FIN,用來關閉被動關閉方到主動關閉方的數據傳送,也就是告訴主動關閉方,我的數據也發送完了,不會再給你發數據了。

    第四次揮手:主動關閉方收到FIN后,發送一個ACK給被動關閉方,確認序號為收到序號+1,至此,完成四次揮手。

    狀態轉換圖

    圖2給出了TCP通信過程中的狀態轉移圖,理解此圖是我們理解TCP-IP協議的關鍵。

    狀態圖詳細解讀:

    CLOSED:起始點,在超時或者連接關閉時候進入此狀態。

    LISTEN:服務端在等待連接過來時候的狀態,服務端為此要調用socket,bind,listen函數,就能進入此狀態。此稱為應用程序被動打開(等待客戶端來連接)。

    SYN_SENT:客戶端發起連接,發送SYN給服務器端。如果服務器端不能連接,則直接進入CLOSED狀態。

    SYN_RCVD:跟3對應,服務器端接受客戶端的SYN請求,服務器端由LISTEN狀態進入SYN_RCVD狀態。同時服務器端要回應一個ACK,同時發送一個SYN給客戶端;另外一種情況,客戶端在發起SYN的同時接收到服務器端得SYN請求,客戶端就會由SYN_SENT到SYN_RCVD狀態。

    ESTABLISHED:服務器端和客戶端在完成3次握手進入狀態,說明已經可以開始傳輸數據了。

    以上是建立連接時服務器端和客戶端產生的狀態轉移說明。相對來說比較簡單明了,如果你對三次握手比較熟悉,建立連接時的狀態轉移還是很容易理解。

    下面,我們來看看連接關閉時候的狀態轉移說明,關閉需要進行4次雙方的交互,還包括要處理一些善后工作(TIME_WAIT狀態),注意,這里主動關閉的一方或被動關閉的一方不是指特指服務器端或者客戶端,是相對于誰先發起關閉請求來說的:

    FIN_WAIT_1:主動關閉的一方,由狀態5進入此狀態。具體的動作是發送FIN給對方。

    FIN_WAIT_2:主動關閉的一方,接收到對方的FIN-ACK(即fin包的回應包),進入此狀態。

    CLOSE_WAIT:接收到FIN以后,被動關閉的一方進入此狀態。具體動作是接收到FIN,同時發送ACK。(之所以叫close_wait可以理解為被動關閉方此時正在等待上層應用發出關閉連接指令)

    LAST_ACK:被動關閉的一方,發起關閉請求,由狀態8進入此狀態。具體動作是發送FIN給對方,同時在接收到ACK時進入CLOSED狀態。

    CLOSING:兩邊同時發起關閉請求時,會由FIN_WAIT_1進入此狀態。具體動作是接收到FIN請求,同時響應一個ACK。

    TIME_WAIT:最糾結的狀態來了。從狀態圖上可以看出,有3個狀態可以轉化成它,我們一一來分析:?
    a. 由FIN_WAIT_2進入此狀態:在雙方不同時發起FIN的情況下,主動關閉的一方在完成自身發起的關閉請求后,接收到被動關閉一方的FIN后進入的狀態。?
    b. 由CLOSING狀態進入:雙方同時發起關閉,都做了發起FIN的請求,同時接收到了FIN并做了ACK的情況下,由CLOSING狀態進入。?
    c. 由FIN_WAIT_1狀態進入:同時接受到FIN(對方發起),ACK(本身發起的FIN回應),與b的區別在于本身發起的FIN回應的ACK先于對方的FIN請求到達,而b是FIN先到達。這種情況概率最小。

    關閉的4次連接最難理解的狀態是TIME_WAIT,存在TIME_WAIT的2個理由:

    可靠地實現TCP全雙工連接的終止。 允許老的重復分節在網絡中消逝。

    附:

    慢熱啟動算法 – Slow Start

    首先,我們來看一下TCP的慢熱啟動。慢啟動的意思是,剛剛加入網絡的連接,一點一點地提速,不要一上來就像那些特權車一樣霸道地把路占滿。新同學上高速還是要慢一點,不要把已經在高速上的秩序給搞亂了。

    慢啟動的算法如下(cwnd全稱Congestion Window):

    1)連接建好的開始先初始化cwnd = 1,表明可以傳一個MSS大小的數據。

    2)每當收到一個ACK,cwnd++; 呈線性上升

    3)每當過了一個RTT,cwnd = cwnd*2; 呈指數讓升

    4)還有一個ssthresh(slow start threshold),是一個上限,當cwnd >= ssthresh時,就會進入“擁塞避免算法”(后面會說這個算法)

    所以,我們可以看到,如果網速很快的話,ACK也會返回得快,RTT也會短,那么,這個慢啟動就一點也不慢。

    擁塞避免算法 – Congestion Avoidance

    前面說過,還有一個ssthresh(slow start threshold),是一個上限,當cwnd >= ssthresh時,就會進入“擁塞避免算法”。一般來說ssthresh的值是65535,單位是字節,當cwnd達到這個值時后,算法如下:

    1)收到一個ACK時,cwnd = cwnd + 1/cwnd

    2)當每過一個RTT時,cwnd = cwnd + 1

    這樣就可以避免增長過快導致網絡擁塞,慢慢的增加調整到網絡的最佳值。很明顯,是一個線性上升的算法。

    擁塞狀態時的算法

    前面我們說過,當丟包的時候,會有兩種情況:

    1)等到RTO超時,重傳數據包。TCP認為這種情況太糟糕,反應也很強烈。

    view sourceprint?

    1.<code?class=" hljs fix">sshthresh =? cwnd /2

    2.cwnd 重置為?1

    3.進入慢啟動過程</code>

    2)Fast Retransmit算法,也就是在收到3個duplicate ACK時就開啟重傳,而不用等到RTO超時。

    TCP Tahoe的實現和RTO超時一樣。

    view sourceprint?

    1.<code?class=" hljs makefile">TCP Reno的實現是:

    2.cwnd = cwnd /2

    3.sshthresh = cwnd

    4.進入快速恢復算法——Fast Recovery</code>

    上面我們可以看到RTO超時后,sshthresh會變成cwnd的一半,這意味著,如果cwnd<=sshthresh時出現的丟包,那么TCP的sshthresh就會減了一半,然后等cwnd又很快地以指數級增漲爬到這個地方時,就會成慢慢的線性增漲。我們可以看到,TCP是怎么通過這種強烈地震蕩快速而小心得找到網站流量的平衡點的。

    快速恢復算法 – Fast Recovery

    這個算法定義在RFC5681。快速重傳和快速恢復算法一般同時使用。快速恢復算法是認為,你還有3個Duplicated Acks說明網絡也不那么糟糕,所以沒有必要像RTO超時那么強烈。 注意,正如前面所說,進入Fast Recovery之前,cwnd和sshthresh已被更新:

    view sourceprint?

    1.<code?class=" hljs ini">cwnd = cwnd /2

    2.sshthresh = cwnd</code>

    然后,真正的Fast Recovery算法如下:

    cwnd = sshthresh + 3 * MSS(3的意思是確認有3個數據包被收到了)?
    重傳Duplicated ACKs指定的數據包.如果再收到 duplicated Acks,那么cwnd = cwnd +1。如果收到了新的Ack,那么,cwnd = sshthresh ,然后就進入了擁塞避免的算法了。

    如果你仔細思考一下上面的這個算法,你就會知道,上面這個算法也有問題,那就是——它依賴于3個重復的Acks。注意,3個重復的Acks并不代表只丟了一個數據包,很有可能是丟了好多包。但這個算法只會重傳一個,而剩下的那些包只能等到RTO超時,于是,進入了惡夢模式——超時一個窗口就減半一下,多個超時會超成TCP的傳輸速度呈級數下降,而且也不會觸發Fast Recovery算法了。

    TCP New Reno

    于是,1995年,TCP New Reno(參見RFC 6582)算法提出來,主要就是在沒有SACK的支持下改進Fast Recovery算法的——?
    當sender這邊收到了3個Duplicated Acks,進入Fast Retransimit模式,開發重傳重復Acks指示的那個包。如果只有這一個包丟了,那么,重傳這個包后回來的Ack會把整個已經被sender傳輸出去的數據ack回來。如果沒有的話,說明有多個包丟了。我們叫這個ACK為Partial ACK。

    一旦Sender這邊發現了Partial ACK出現,那么,sender就可以推理出來有多個包被丟了,于是乎繼續重傳sliding window里未被ack的第一個包。直到再也收不到了Partial Ack,才真正結束Fast Recovery這個過程。

    我們可以看到,這個“Fast Recovery的變更”是一個非常激進的玩法,他同時延長了Fast Retransmit和Fast Recovery的過程。

術語:

SYN表示建立連接,

FIN表示關閉連接,

ACK表示響應,

PSH表示有 DATA數據傳輸,

RST表示連接重置。

http://www.cnblogs.com/azraelly/archive/2012/12/25/2832393.html

轉載于:https://blog.51cto.com/danniea/1642489

總結

以上是生活随笔為你收集整理的图解TCPIP协议的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。