[Linux]經典面試題 - 網路基礎 - TCP三次握手

SkyBiuBiu發表於2021-06-20

[Linux]經典面試題 - 網路基礎 - TCP三次握手

參考:

一、TCP報文格式

1.1 TCP報頭

image-20210620132120829

TCP的報頭有20位元組,一共160位,其中包括以下內容:

  • 源埠號(16位):發起連線埠。
  • 目的埠號(16位):接受連線埠。
  • 序列號(seq,32位):
    • 如果含有同步化旗標(SYN),則此為最初的序列號;第一個資料位元的序列碼為本序列號加一。
    • 如果沒有同步化旗標(SYN),則此為第一個資料位元的序列碼。
  • 確認號(ack,32位):僅當ACK標誌為1時有效,確認號表示期望收到的下一個位元組的序號。
  • 資料偏移(4位):以4位元組為單位計算出的資料段開始地址的偏移值。
  • 保留(6位):置零。
  • 識別符號(6位):
    • URG:1,緊急指標欄位有效。
    • ACK:1,確認號欄位有效。
    • PSH:1,接收方應儘快將報文交給引用層。
    • RST:1,出現嚴重差錯,可能要重新建立TCP請求。
    • SYN:1,表示這是連線請求或是連線接受請求,用於建立連線和使順序號同步。
    • FIN:1,表示傳送方沒有資料要傳輸了,要求釋放連線。
  • 視窗(window,16位):表示從確認號開始,本報文的傳送方可以接收的位元組數,即接受視窗
    的大小,用於流量控制。
  • 校驗和(checksum,16位):對整個的TCP報文段,包括TCP頭部和TCP資料,以16位字進行計算所得。這是一個強制性的欄位。
  • 緊急指標(16位):本報文段中的緊急資料的最後一個位元組的序號。

1.2 報文圖例

[Linux]經典面試題 - 網路基礎 - TCP三次握手

二、TCP三次握手

2.1 運作方式

  • TCP協議的執行可以分為三個階段:連線建立、資料傳送、連線中止

  • 作業系統將TCP連線抽象為套接字表示的本地端點,作為程式設計介面給程式用。

  • 一對終端同時初始化一個它們之間的連線是可能的。但通常是由一端(伺服器端)開啟一個套接字(socket)然後監聽來自另一方(客戶端)的連線,這就是通常所指的被動開啟。伺服器端被被動開啟以後,客戶端就能開始建立主動開啟。

  • 伺服器端執行了listen函式後,就在伺服器上建立起兩個佇列:

    • SYN佇列:存放完成了二次握手的結果。
    • ACCEPT佇列:存放完成了三次握手的結果。

2.2 建立過程

image-20210620141317482

為了保證資料能夠到達目標,TCP採用三次握手的策略,過程如下:

  1. 客戶端向服務端傳送一個SYN包,請求一個主動開啟。該包攜帶客戶端為這個連線請求而設定的隨機數A作為訊息序列號。
  2. 服務端收到一個合法的SYN包後,把該包放入SYN佇列中;回送一個SYN/ACK。ACK的確認碼應為A+1,SYN/ACK包本身攜帶一個隨機產生的序列號B
  3. 客戶端收到SYN/ACK包後,傳送一個ACK包,該包的序號被設定為A+1,而ACK的確認碼為B+1

2.3 抓包分析

(待補充)

三、TCP四次揮手

3.1 斷開過程

image-20210620144646555

斷開過程如下:

  1. 主動斷開方(客戶端/服務端)-傳送一個 FIN,用來關閉主動斷開方(客戶端/服務端)到被動斷開方(客戶端/服務端)的資料傳送
  2. 被動斷開方(客戶端/服務端)-收到這個 FIN,它發回一 個 ACK,確認序號為收到的序號加1 。和 SYN 一樣,一個 FIN 將佔用一個序號
  3. 被動點開方(客戶端/服務端)-關閉與主動斷開方(客戶端/服務端)的連線,傳送一個FIN給主動斷開方(客戶端/服務端)
  4. 主動斷開方(客戶端/服務端)-發回 ACK 報文確認,並將確認序號設定為收到序號加1

相關文章