[Linux]經典面試題 - 網路基礎 - TCP三次握手
目錄
參考:
一、TCP報文格式
1.1 TCP報頭
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 報文圖例
二、TCP三次握手
2.1 運作方式
-
TCP協議的執行可以分為三個階段:連線建立、資料傳送、連線中止。
-
作業系統將TCP連線抽象為套接字表示的本地端點,作為程式設計介面給程式用。
-
一對終端同時初始化一個它們之間的連線是可能的。但通常是由一端(伺服器端)開啟一個套接字(socket)然後監聽來自另一方(客戶端)的連線,這就是通常所指的被動開啟。伺服器端被被動開啟以後,客戶端就能開始建立主動開啟。
-
伺服器端執行了listen函式後,就在伺服器上建立起兩個佇列:
- SYN佇列:存放完成了二次握手的結果。
- ACCEPT佇列:存放完成了三次握手的結果。
2.2 建立過程
為了保證資料能夠到達目標,TCP採用三次握手的策略,過程如下:
- 客戶端向服務端傳送一個SYN包,請求一個主動開啟。該包攜帶客戶端為這個連線請求而設定的隨機數A作為訊息序列號。
- 服務端收到一個合法的SYN包後,把該包放入SYN佇列中;回送一個SYN/ACK。ACK的確認碼應為A+1,SYN/ACK包本身攜帶一個隨機產生的序列號B。
- 客戶端收到SYN/ACK包後,傳送一個ACK包,該包的序號被設定為A+1,而ACK的確認碼為B+1。
2.3 抓包分析
(待補充)
三、TCP四次揮手
3.1 斷開過程
斷開過程如下:
- 主動斷開方(客戶端/服務端)-傳送一個 FIN,用來關閉主動斷開方(客戶端/服務端)到被動斷開方(客戶端/服務端)的資料傳送
- 被動斷開方(客戶端/服務端)-收到這個 FIN,它發回一 個 ACK,確認序號為收到的序號加1 。和 SYN 一樣,一個 FIN 將佔用一個序號
- 被動點開方(客戶端/服務端)-關閉與主動斷開方(客戶端/服務端)的連線,傳送一個FIN給主動斷開方(客戶端/服務端)
- 主動斷開方(客戶端/服務端)-發回 ACK 報文確認,並將確認序號設定為收到序號加1