TCP三次握手和四次揮手
TCP三次握手和四次揮手詳解
在網絡通信中,TCP(傳輸控制協議)是一個非常重要的協議,用于確保數據在不可靠的網絡環境中能夠可靠傳輸。TCP通過三次握手(Three-way Handshake)建立連接,通過四次揮手(Four-way Termination)終止連接。
一、TCP三次握手
TCP的三次握手用于確保客戶端和服務器之間的連接是可靠的,并且雙方都準備好進行數據傳輸。三次握手的過程如下:
-
第一次握手:客戶端發送SYN
- 客戶端向服務器發送一個SYN(同步序列編號)報文,表示客戶端希望與服務器建立連接。此時,客戶端進入SYN-SENT狀態。
- 報文中包含一個初始序列號(ISN),用于后續數據傳輸中的序列控制。
-
第二次握手:服務器發送SYN-ACK
- 服務器接收到SYN報文后,向客戶端發送一個SYN-ACK(同步確認)報文,表示同意建立連接。此時,服務器進入SYN-RECEIVED狀態。
- SYN-ACK報文包含服務器自己的ISN和客戶端的ISN+1,表明服務器已收到客戶端的SYN,并將自己的SYN發送給客戶端。
-
第三次握手:客戶端發送ACK
- 客戶端接收到SYN-ACK報文后,向服務器發送一個ACK(確認)報文,確認服務器的SYN已經收到。此時,客戶端進入ESTABLISHED狀態,連接建立成功。
- 服務器接收到ACK報文后,也進入ESTABLISHED狀態,表示連接已準備好進行數據傳輸。
通過三次握手,雙方確認了彼此的發送和接收能力,連接正式建立。
這個過程類似于打電話的三個過程:
1.撥號。撥號相當于第一次握手。
2.接通。對方接通后為第二次握手。
3.回應。我方聽到聲音并回應為第三次握手。
二、TCP四次揮手
TCP的四次揮手用于終止客戶端和服務器之間的連接,確保雙方都能夠優雅地關閉連接。四次揮手的過程如下:
-
第一次揮手:客戶端發送FIN
- 客戶端發送一個FIN(終止)報文,表示客戶端已經沒有數據要發送了,要求關閉連接。此時,客戶端進入FIN-WAIT-1狀態。
- FIN報文可能包含最后一段數據,或者僅僅表示終止發送。
-
第二次揮手:服務器發送ACK
- 服務器接收到FIN報文后,向客戶端發送一個ACK報文,確認客戶端的FIN已經收到。此時,服務器進入CLOSE-WAIT狀態,客戶端進入FIN-WAIT-2狀態。
- 此時,服務器可能仍有未發送的數據,因此不會立即關閉連接。
-
第三次揮手:服務器發送FIN
- 服務器發送完所有剩余的數據后,向客戶端發送一個FIN報文,表示服務器也準備關閉連接。此時,服務器進入LAST-ACK狀態。
- 客戶端接收到FIN報文后,發送最后一個ACK報文,確認收到服務器的FIN。此時,客戶端進入TIME-WAIT狀態。
-
第四次揮手:客戶端發送ACK
- 客戶端發送的最后一個ACK報文確認了服務器的FIN報文后,客戶端進入TIME-WAIT狀態,等待一段時間(通常為2倍的最大報文段壽命),確保服務器收到ACK。
- 如果在TIME-WAIT狀態期間沒有收到任何重傳的FIN報文,客戶端將進入CLOSED狀態,表示連接已經完全關閉。
通過四次揮手,TCP連接得以優雅地關閉,確保所有的數據都得到了完整的傳輸和確認。
示例:
import socket import time # 服務端代碼 def server(): # 創建TCP套接字 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 綁定IP地址和端口號 server_socket.bind(('localhost', 12345)) # 監聽連接請求 server_socket.listen(1) print("Server is listening...") # 接受客戶端連接 conn, addr = server_socket.accept() print(f"Connected by {addr}") # 模擬服務器發送數據 conn.sendall(b'Hello, Client!') # 接收客戶端消息 data = conn.recv(1024) print(f"Received: {data.decode()}") # 關閉連接 conn.close() server_socket.close() print("Server connection closed.") # 客戶端代碼 def client(): # 創建TCP套接字 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 連接服務器 client_socket.connect(('localhost', 12345)) print("Client connected to server.") # 接收服務器消息 data = client_socket.recv(1024) print(f"Received: {data.decode()}") # 模擬客戶端發送數據 client_socket.sendall(b'Thank you, Server!') # 關閉連接 client_socket.close() print("Client connection closed.") # 模擬TCP三次握手和四次揮手 if __name__ == "__main__": # 啟動服務端 import threading server_thread = threading.Thread(target=server) server_thread.start() # 延遲啟動客戶端以確保服務端已啟動 time.sleep(1) # 啟動客戶端 client() # 等待服務端線程結束 server_thread.join()
-
服務端部分:
- 使用
socket.socket()創建一個TCP套接字,并綁定到localhost上的端口12345。 - 通過
listen()方法讓服務器開始監聽客戶端連接。 - 使用
accept()接受客戶端的連接請求,并返回一個新的套接字conn,用于與客戶端進行通信。 - 服務器發送一條消息給客戶端,并接收客戶端的響應后,關閉連接。
- 使用
-
客戶端部分:
- 同樣使用
socket.socket()創建一個TCP套接字。 - 通過
connect()方法連接到服務器的IP和端口。 - 客戶端接收到服務器的消息后,發送一個響應消息,并關閉連接。
- 同樣使用
-
主程序部分:
- 使用Python的
threading模塊來同時運行服務器和客戶端,模擬TCP的三次握手和四次揮手過程。
- 使用Python的
輸出:
Server is listening... Client connected to server. Connected by ('127.0.0.1', random_port) Received: Hello, Client! Received: Thank you, Server! Client connection closed. Server connection closed.

浙公網安備 33010602011771號