三次握手與四次揮手
所謂三次握手(Three-way Handshake),是指建立一個 TCP 連接時,需要客戶端和服務器總共發送3個包。
三次握手的目的是連接服務器指定端口,建立 TCP 連接,並同步連接雙方的序列號和確認號,交換 TCP 窗口大小信息。在 socket 編程中,客戶端執行 connect()
時。將觸發三次握手。
-
第一次握手(SYN=1, seq=x):
客戶端發送一個 TCP 的 SYN 標志位置1的包,指明客戶端打算連接的服務器的端口,以及初始序號 X,保存在包頭的序列號(Sequence Number)字段里。
發送完畢后,客戶端進入
SYN_SEND
狀態。 -
第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):
服務器發回確認包(ACK)應答。即 SYN 標志位和 ACK 標志位均為1。服務器端選擇自己 ISN 序列號,放到 Seq 域里,同時將確認序號(Acknowledgement Number)設置為客戶的 ISN 加1,即X+1。 發送完畢后,服務器端進入
SYN_RCVD
狀態。 -
第三次握手(ACK=1,ACKnum=y+1)
客戶端再次發送確認包(ACK),SYN 標志位為0,ACK 標志位為1,並且把服務器發來 ACK 的序號字段+1,放在確定字段中發送給對方,並且在數據段放寫ISN的+1
發送完畢后,客戶端進入
ESTABLISHED
狀態,當服務器端接收到這個包時,也進入ESTABLISHED
狀態,TCP 握手結束。
三次握手的過程的示意圖如下:
TCP 的連接的拆除需要發送四個包,因此稱為四次揮手(Four-way handshake),也叫做改進的三次握手。客戶端或服務器均可主動發起揮手動作,在 socket 編程中,任何一方執行 close()
操作即可產生揮手操作。
-
第一次揮手(FIN=1,seq=x)
假設客戶端想要關閉連接,客戶端發送一個 FIN 標志位置為1的包,表示自己已經沒有數據可以發送了,但是仍然可以接受數據。
發送完畢后,客戶端進入
FIN_WAIT_1
狀態。 -
第二次揮手(ACK=1,ACKnum=x+1)
服務器端確認客戶端的 FIN 包,發送一個確認包,表明自己接受到了客戶端關閉連接的請求,但還沒有准備好關閉連接。
發送完畢后,服務器端進入
CLOSE_WAIT
狀態,客戶端接收到這個確認包之后,進入FIN_WAIT_2
狀態,等待服務器端關閉連接。 -
第三次揮手(FIN=1,seq=y)
服務器端准備好關閉連接時,向客戶端發送結束連接請求,FIN 置為1。
發送完畢后,服務器端進入
LAST_ACK
狀態,等待來自客戶端的最后一個ACK。 -
第四次揮手(ACK=1,ACKnum=y+1)
客戶端接收到來自服務器端的關閉請求,發送一個確認包,並進入
TIME_WAIT
狀態,等待可能出現的要求重傳的 ACK 包。服務器端接收到這個確認包之后,關閉連接,進入
CLOSED
狀態。客戶端等待了某個固定時間(兩個最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,沒有收到服務器端的 ACK ,認為服務器端已經正常關閉連接,於是自己也關閉連接,進入
CLOSED
狀態。
四次揮手的示意圖如下: