?一、前置知識
? TCP是一種面向連接的、可靠的、基于字節流的傳輸層通信協議。在傳輸數據前通信雙方必須建立連接(所謂連接,是指客戶端和服務端各自保存一份關于對方的信息,比如ip地址,端口號等)。TCP通過三次握手建立一個連接,通過四次揮手釋放一個連接。
? 在了解TCP連接前,先了解TCP報文的頭部結構:
??TCP報文段的頭部結構主要包含以下幾個部分:
1.源端口和目的端口(Source port,Destination port):這兩個字段用來標識發送端和接收端的端口號,占16位。
2.序列號(Sequence number):占32位,用來標識從TCP源端向目的端發送的字節流。當發起方發送數據時,會對這些數據進行標記,確保數據的有序性和完整性。(seq)
3.確認序號(Acknowledgement number):占32位,只有在ACK標志位為1時,這個字段才有效。它表示接收方已經成功接收到的數據的序列號(ack=seq+1)。
4.標志位:占6位,包含URG、ACK、PSH、RST、SYN、FIN等標志。其中ACK表示確認序號有效,FIN表示釋放一個連接,SYN表示發起一個新連接。
二、TCP的三次握手
? 三次握手就是通過三次數據包的交換,來確認通信雙方收發數據的能力。
- 一開始,客戶端和服務端都處于CLOSE狀態,服務端監聽客戶端的請求,進入LISTEN狀態。
- 第一次握手(客戶端發送連接請求):客戶端會向服務端發送一個SYN包,里面包含了客戶端的初始序列號。然后客戶端進入SYN_SENT狀態。
- 第二次握手(服務端確認收到了客戶端的連接請求):回復客戶端一個SYN+ACK包,里面包含確認信息(表示收到了客戶端的SYN包)和服務端的初始序列號。然后服務端進入SYN_RCVD(received的縮寫)狀態。
- 第三次握手(客戶端收到服務端的確認后,再次向服務端確認):再回復一個ACK包給服務端。然后客戶端進入ESTABLISHED狀態,當服務端接收到這個ACK包后,也進入ESTABLISHED狀態。
- 這樣客戶端和服務端之間就建立了一個可靠的連接,可以開始傳輸數據。
三、TCP的四次揮手
- 數據傳輸結束后,通信雙方都可以主動發起釋放連接請求,假設由客戶端發起。
- 第一次揮手(客戶端發送釋放連接請求):客戶端向服務端發送一個FIN包,并附帶一個序列號。然后,客戶端進入FIN_WAIT1狀態。
- 第二次揮手(服務端確認收到了客戶端釋放連接的請求):回復一個ACK包,同時包含一個確認號。然后,服務端進入CLOSE_WAIT狀態(此時服務端還沒準備好釋放連接,可能還有數據要處理),當客戶端收到服務端的這個ACK包后,進入FIN_WAIT2狀態。
- 第三次揮手(服務端也已經準備好釋放連接):向客戶端發送一個FIN包,并附帶一個序列號。然后,服務端進入LAST_ACK狀態,表示等待來自客戶端的最后一個ACK包。
- 第四次揮手(客戶端確認服務端也已經準備好釋放連接):就回復一個ACK包,但是此時客戶端不會馬上關閉連接,而是進入TIME_WAIT狀態,等待某個固定時間(2MSL,2 Maximum Segment LifeTime,兩倍的最長報文段生命周期),目的是防止這個ACK包丟失,導致服務端沒有收到客戶端關閉連接的確認,沒有關閉連接,就會超時重傳FIN包。那么等待這個固定時間后(即是確保服務端已經正常關閉連接后),客戶端才關閉連接,進入CLOSED狀態。當服務端收到這個ACK包后,就關閉連接,進入CLOSED狀態。
- 這樣就成功釋放連接了。