看圖理解TCP的三次握手和四次揮手

AlexShan發表於2018-04-06

閱讀時間:8min 閱讀目標:

  1. 掌握TCP連線過程
  2. 學會計算seq、ack碼

TCP 協議是HTTP協議的重要基礎,充分理解TCP協議的連線及埠,有助於我們深入理解網路請求和連線。今天就來看圖學習TCP請求的連線、資料傳輸及埠連線。


OSI7層網路模型

OSI是Open System Interconnection的縮寫,國際標準化組織(ISO)制定了OSI模型,該模型定義了不同計算機互聯的標準,是設計和描述計算機網路通訊的基本框架。

參考模型(從上至下) 各層含義
應用層 為應用程式提供服務,如HTTP、FTP、SMTP、POP3等
表示層 資料格式轉換翻譯、資料加密解密、壓縮解壓縮
會話層 不同機器之間的使用者建立及管理會話
傳輸層 建立管理和維護端到端的連線,TCP、UDP
網路層 IP地址及路由選擇
資料鏈路層 物理定址,將原始位元流轉化為邏輯傳輸線路
物理層 機械、電子、定時介面通訊通道上上的原始位元流傳輸

1. 傳輸層

接受上一次的資料,將資料進行分割,保證資料準確到達對端。

2. TCP

TCP是面向連線的無狀態的協議。為了連線的可靠性,每次連線的建立都需要3次握手。

2.1 建立連線(3次握手)

3次握手的目的:

  1. 同步連線雙方的序列號和確認號;
  2. 交換TCP視窗大小資訊。
客戶端(狀態) 建立連線(三次握手) 服務端(狀態)
CLOSED LISTEN
SYN seq=0 ==》
SYN_SENT
《== SYN ACK ack=1,seq=0
SYN_RCVD
ACK ack=1,seq=1 ==》
ESTABLISHED ESTABLISHED
  • 第一次握手: 建立連線。客戶端傳送連線請求,傳送SYN報文,隨機生成seq,本例預設為0。然後,客戶端進入SYN_SEND狀態,等待伺服器的確認。
  • 第二次握手: 伺服器收到客戶端的SYN報文段。需要對這個SYN報文段進行確認,傳送ACK報文,將ack設定為1(ack值為對方seq+1或者seq+L(資料長度L))。同時,自己還要傳送SYN請求資訊,將seq為0。伺服器端將上述所有資訊一併傳送給客戶端,此時伺服器進入SYN_RECV狀態。
  • 第三次握手: 客戶端收到伺服器的ACK和SYN報文後,進行確認,然後將ack設定為1,seq設定為1,向伺服器傳送ACK報文段,這個報文段傳送完畢以後,客戶端和伺服器端都進入ESTABLISHED狀態,完成TCP三次握手。

2.2 資料傳輸

客戶端 資料傳輸 服務端
PSH seq=1, ACK ack=1(segmentLen = 99) ==》
《== PSH seq=1, ACK ack=100 (segmentLen = 119)
ACK ack=120,seq=100 ==》
  • 客戶端先向伺服器傳送資料,該資料包是長度為99的資料。
  • 伺服器收到報文後, 也向客戶端傳送了一個資料進行確認(ACK),並且返回客戶端要請求的資料,資料的長度為111,將seq設定為1,ack設定為120(1 + 119)。
  • 客戶端收到伺服器返回的資料後進行確認(ACK),將seq設定為100, ack設定為112(1 + 111)。

2.3 斷開連結(4次揮手)

客戶端(狀態) 斷開連線 服務端(狀態)
FIN ACK ack=120,seq=100 ==》
FIN_WAIT_1
《== ACK ack=101,seq=120
FIN_WAIT_2 CLOSE_WAIT
《== ACK ack=101,seq=120
LAST_ACK
ACK ack=121,seq=101 ==》
TIME_WAIT CLOSE
  • 第一次揮手:客戶端向伺服器傳送一個FIN報文段,將設定seq為100和ack為120,;此時,客戶端進入 FIN_WAIT_1狀態,這表示客戶端沒有資料要傳送伺服器了,請求關閉連線;
  • 第二次揮手:伺服器收到了客戶端傳送的FIN報文段,向客戶端回一個ACK報文段,ack設定為101,seq設定為120;伺服器進入了CLOSE_WAIT狀態,客戶端收到伺服器返回的ACK報文後,進入FIN_WAIT_2狀態;
  • 第三次揮手:伺服器會觀察自己是否還有資料沒有傳送給客戶端,如果有,先把資料傳送給客戶端,再傳送FIN報文;如果沒有,那麼伺服器直接傳送FIN報文給客戶端。請求關閉連線,同時伺服器進入LAST_ACK狀態;
  • 第四次揮手:客戶端收到伺服器傳送的FIN報文段,向伺服器傳送ACK報文段,將seq設定為101,將ack設定為121,然後客戶端進入TIME_WAIT狀態;伺服器收到客戶端的ACK報文段以後,就關閉連線;此時,客戶端等待2MSL後依然沒有收到回覆,則證明Server端已正常關閉,客戶端也可以關閉連線了。

** 計算規則: ** seq 為序列號 ack 為應答碼 seq = 對方上次的ack;(首次傳送時seq為系統隨機生成) ack = 對方的seq+1(無資料傳輸時) 或者 seq+L(報文資料的長度L)

相關文章