傳輸層 ,TCP 為什么是三次握手?


傳輸層主要的作用就是建立端到端的連接。比如電腦的微信的通信,就需要跨越多個網絡設備(交換機和路由器)再和微信的服務器建立連接。

傳輸層需要具有以下的特點:

  • 會話的多復用:如電腦上開啟的多個應用,QQ,微信等,這就意味着同時需要建立多個會話。
  • 識別應用程序:通過端口號,來區分不同的應用程序。
  • 分段:在發送數據時,將數據段分為多個部分進行發送,然后在接收端重新組裝這些數據段。(TCP)
  • 流量控制:在發送端和接受端,兩者發送和接受的帶寬不一致時,可以動態的調整帶寬。(TCP)
  • 面向連接:確認對方能接收時再發送(TCP)。
  • 可靠性:保證對方一定能收到數據。(TCP)。

TCP 和 UDP 就是實現上述特點的協議。

TCP 報文段

TCP 連接過程 - 三次握手

三次握手是個老生常談的話題,還得在大學時死記硬背這個連接過程,現在想想還蠻好玩的。都說檢驗一個人是否理解一件事情,就讓他給一個從來沒有聽過的人講,講明白了,自然證明也就懂了。其實這就是主動學習和被動學習的體現,大家有興趣可以查查費曼學習法,講授給他人,寫文章等都是一種主動學習的方式。有點扯遠了,回到三次握手的過程,希望能給大家講清楚。

在談起連接過程前,先要對 TCP Header 中這幾個字段有一個清晰的了解,在上面的導圖也提到了,下面着重強調一下:

關於 Flag 字段: 該字段是 1 Byte,共 8 位,如果每一位置 1 后,就代表該 TCP 報文開啟了對應的功能,其中三次握手共涉及 3 個字段,注意我這里是用大寫的表示,並且只有 1 和 0 兩種狀態:

  • SYN 字段:當置 1 時,表示該報文是請求連接的報文段,用於在 TCP 連接時的第一個連接。
  • ACK 字段:當置 1 時,表示該報文是確認報文,用於表示對方發的請求連接已經收到,這里給予確認。
  • FIN 字段:當置 1 時,表示發送方已經發送完畢,請求關閉連接。

關於序號字段 seq: 注意這里是小寫,共有 4 Byte,32 位。和 IP 層一樣,有時當發送的數據超過固定的 MTU 大小時,會將數據包拆成多個小的數據包發送,但數據是有順序要求,為了保證數據的順序,就有了該字段 seq,用於表示第一個字節在整個字節流的標號。

關於確認號字段 ack: 和 seq 一樣,4 Byte. 表示對收到的數據進行確認,並告訴發送方接下來期待的序列號是什么。

最后還需要明確一點,TCP 建立的是雙向的連接,因為在端點的另一方可以是發送方也可能是接收方,明確這點非常重要。

上面看起來比較抽象,一會實際抓包,對照起來看就清晰了。先有個印象,先來分析下 TCP 的連接過程。

一個 TCP 連接會有三個狀態:

  • 建立連接的狀態
  • 傳輸數據的狀態
  • 關閉連接的轉台

先看連接狀態:

  1. 客戶端想要和服務端建立連接:置位 Flag 字段中的 SYN=1,表示請求建立連接。seq = x,表示傳送的第一個字節的序號是 x.

  2. 服務端收到客戶端請求:

    1. 置位 Flag 字段中的 ACK=1,表示確認跟你連接鏈接。ack= x + 1,表示前 x 個字節已經收到,期待傳送 x+1個字節。
    2. 由於剛才連接過程是客戶端到服務端的,同樣的,服務端也需要向客戶端也發一個請求用於建立連接,這樣才是雙向連接。正常來說,服務端應該再發一個請求,但由於 TCP 的報頭設計,可以將請求功能和確認功能放在一個數據包里,通過 Flag 同時置位 SYN 和 ACK 。這也就是為什么連接時,三次握手而不是四次。
  3. 客戶端收到服務端的回復,通過 ack=x+1 知道,服務端收到了 x 字節的數據,期待接受 x+1 字節的數據。通過 SYN=1,seq=y 知道服務端想要和自己連接連接。進而回復 ACK=1,seq=x+1,ack=y+1.

傳輸狀態:

如何保證數據的可靠性傳輸?

在客戶端給服務傳輸數據時,如果收到 ACK 的報文,則代表服務端確實收到了傳遞的數據。考慮這樣一種情況,客戶端向服務端發送了 seq=10 的報文,但卻收到服務端 ack=10 的回復。其實這就代表着,存在丟包的情況,服務端並未收到客戶端 seq=10 的包。這時服務端會重新發送 seq=10 的報文,也就是說,在客戶端只有成功的接收了服務端的 ACK 包,才會繼續向下傳遞。

如何進行流量控制?

在 TCP Header 中有一個叫窗口大小的字段。當路由器發送或者接收數據時,會將數據先緩存起來,這個窗口就是對應的緩存區。由於造價的不同,不同的設備對應的緩沖區大小也不一樣。考慮這樣一種情況,客戶端的窗口大小為 3 Byte,但服務端的窗口大小為 2 Byte。這就意味着,服務端只能先緩存 2 Byte 的數據。接着來看下,TCP 是如何進行流量控制的:

  • 第一次,客戶端會給服務端直接發送 3 Byte 的數據,注意是通過一個包里面包含 3 Byte 的數據。但由於服務端只有 2 Byte 的緩存空間,第三個 Byte 的內容會被丟掉。
  • 接着服務端會回報,進行 ACK 確認,發送 ack=3,代表接受到了 seq=2 之前的數據。同時還會發送窗口大小 WS(2)告訴客戶端自己只有 2 Byte 的緩存空間。
  • 之后客戶端只會發送緩存空間為 2 的數據包給服務端。

考慮一種特殊的情況:

在服務端收到 2 Byte 的數據時,此時 CPU 的處理變得低效,只從緩沖空間中取出了 1 個字節發送終端。

這時服務端再給客戶端回包時,除了正常回復 ack=x+1 的確認,還會改變窗口大小為 1.,這就意味着告訴服務端,下次給我發包時
只能接受一個 Byte 的數據。

實際抓包看一下,這里以訪問百度為例子:

第一次握手:

結合之前說的:

  • 在 Flag 字段中,SYN 置1,表示這是一個請求連接的報文。
  • seq=0,注意這里的 0 只是抓包軟件的相對值,真實值是下面的 ac f7 f8 8b.
  • 源端口為:8548
  • 目的端口為:443

再看第二次握手:

同樣:

  • 服務端再 Flag 為 SYN 和 ACK 置位,表示該報具有確認和請求連接的功能。
  • ack = ac f7 f8 8c 正好是之前 seq 的大小 +1.
  • seq = 0,其實這里也是相對的位置,真實值為 fd 15 e1 c4,在 ack 的前四字節就是 syn.

最后第三次握手:

  • 表示客戶端確認和服務建立連接,對應 Flag ACK 置位。
  • ack = fd 15 e1 c5, fd 15 e1 c4 + 1.

斷開連接:

理解了 TCP 連接的過程,再看斷開連接就很容易了。一樣的,首先要明確,已經建立的連接是雙向的連接。如果想要斷開的話,自然雙方都要發起一個請求。

而報文內部也大致相同,僅僅是把 Flag 字段中 SYN 換成 FIN 字段,表示想要斷開連接。

同樣,假如有客戶端和服務端已經建立了連接。

  1. 客戶端向服務端發送報文,其中 FIN=1,表示請求斷開連接。(斷開的是客戶端到服務端的連接)
  2. 服務端收到后回包,ACK=FIN+1,表示收到客戶端的情況,確認斷開。
  3. 服務端再次發送請求,置位 FIN=1,表示要和服務端斷開連接。(斷開的是服務端到客戶端的連接)
  4. 客戶端收到后,ACK=FIN+1,表示確認斷開和服務的連接。

這里一定會有疑問,為什么在三次握手中,可以在一個數據包中同時置位 SYN 和 ACK 表示確認和請求連接的過程,等到了斷開連接時,就不能這樣做呢,而是需要發送兩次。

原因就在於,由於連接是雙向的,第1,2步驟表示,客戶端已經沒有數據發送給服務端了。但這時,服務端可能還有數據正在發送給客戶端,等待數據發送完成后。才能進行 3,4 步驟,然后斷開服務端到客戶端的連接。

UDP 報文段

學習了 TCP,再看 UDP 自然就很簡單了。

先看 UDP 的特性:

  • 工作在傳輸層
  • 執行有限制的差錯校驗
  • 提供盡力而為的傳輸
  • 不可能的傳輸
  • 開銷低,傳輸的效率高

可以看到,UDP 的 Header 中,僅有源端口,目的端口用於識別應用程序。

下面來比較一下 TCP 和 UDP:

關於連接的類型:面向連接/面向無連接

序號:TCP 由於是可靠傳輸,所以需要對收到的內容進行 ACK 確認,而 UDP 直接發送,不管對方能不能接受。

應用場景:TCP 要求可靠的通信,如郵件,FTP,瀏覽網頁,下載等服務。而 UDP 則適合語音,視頻,HDCP等等。

總結

傳輸層的作用就是建立端到端的連接,為了實現該功能,一般有兩種協議 TCP 和 UDP 可以選擇。

對於 TCP 來說,需要了解並理解三次握手和四次揮手的過程。比較 TCP 和 UDP 的不同,以及適用的場景。

最后可以用這幾個問題檢驗自己,對應都可以在文章中找到答案:

  1. TCP 在建立連接時,為什么是三次握手而不是四次?
  2. TCP 在斷開連接時,為什么是四次而不是三次?
  3. TCP 是如何保證可靠傳輸的?
  4. TCP 是如何進行流量控制的?
  5. TCP 和 UDP 的區別,以及適用的場景。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM