一、TCP首部結構
TCP首部由20位元組的固定長度組成,其中有12個位元組是固定的,剩餘8個位元組是可選的。TCP首部的結構如下:
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Port | Destination Port | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Sequence Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Acknowledgment Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data |A|C|K|P|R|S|F| Window Size | | Offset|N|E|G|S|S|Y|I| | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Checksum | Urgent Pointer | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Options | Padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
其中,各欄位的含義如下:
– 16位源埠(Source Port):發送方埠號(發送方在本機的標識)
– 16位目的埠(Destination Port):接收方埠號(接收方在本機的標識)
– 32位序列號(Sequence Number):位元組流中的第一個位元組的序列號,為了處理亂序到達的數據包
– 32位確認號(Acknowledgment Number):期望接收的下一位元組的序列號,為了確認對方是否已經接收到自己發出的報文
– 4位報文頭長度(Data Offset):以32位字長為單位的數據偏移量,指定數據從哪個偏移開始
– 6位保留位(RSV):保留,必須是0
– 6位標記位(Flags):6個標誌位,依次分別為URG、ACK、PSH、RST、SYN和FIN
– 16位窗口大小(Window Size):接收端緩衝區大小
– 16位校驗和(Checksum):校驗和,用於檢驗TCP頭部和數據部分的錯誤(軟體實現)
– 16位緊急指針(Urgent Pointer):緊急指針,指出TCP緊急數據的位元組數
– 可選項(Options):根據需要,在TCP頭部中添加一些可選項(如時間戳、SACK選項等)
– 填充(Padding):由於選項長度不一定是4的倍數,因此需要進行填充使長度為4的倍數
二、TCP標誌位
TCP標誌位是TCP首部中很重要的一部分,用於標識TCP連接的狀態和控制TCP報文的傳輸。TCP標誌位包括URG、ACK、PSH、RST、SYN和FIN六種標誌。下面是各標誌位的含義:
– URG:表示TCP報文中有緊急數據,通知對端處理緊急數據
– ACK:表示確認號(Acknowledgment Number)有效,通知發送方已收到對方的數據
– PSH:表示TCP緩存中的數據應立即發送而不是等待緩存填滿
– RST:表示連接複位,通知對端關閉連接
– SYN:表示發起一個新連接
– FIN:表示TCP連接已經關閉
因此,TCP報文的狀態就可以通過標誌位表示。例如,當SYN=1且ACK=0,表示此時正在建立連接;當SYN=1且ACK=1,表示此時連接已經建立;當FIN=1,表示連接正在關閉。
三、TCP窗口大小
TCP窗口大小指的是接收方緩存區的大小,其在TCP傳輸過程中起到了非常重要的作用。接收方通常會不斷將TCP首部中的窗口大小信息發送給發送方,發送方依據此信息動態調整數據發送速率。
在TCP數據傳輸過程中,若發送方發現接收方的窗口大小為0,則會停止發送數據,直到接收方再次通知窗口大小不為0。這樣可以減少網路擁塞的產生。同時,接收方的窗口大小也可以用來反饋網路擁塞信息,當接收方發現自己的窗口大小沒有變大時就會認為網路發生擁塞。
四、TCP擁塞控制
TCP協議通過擁塞窗口(Congestion Window)來實現擁塞控制。當網路擁塞時,TCP發送方就會減小擁塞窗口的大小,從而減少發送速率。擁塞窗口的大小由擁塞避免演算法和擁塞控制演算法共同決定。
擁塞避免演算法是一種保證網路不會過早進入擁塞狀態的演算法,其根據接收方的窗口大小不斷調整擁塞窗口的大小。擁塞控制演算法則是對擁塞狀態進行控制的演算法,其在檢測到網路擁塞時會立即減小擁塞窗口的大小,從而有效控制網路擁塞的發生。
五、TCP頭部可選項
TCP頭部中還可以添加一些可選項,目的是為了支持更多的功能。例如,常用的時間戳選項(Timestamp Option)可以記錄數據包到達時間,以此來計算延遲等網路性能指標。另外,選擇性確認選項(Selective Acknowledgment Option,SACK)也是TCP頭部中常用的一種選項,可以用來減少重傳的數據大小,提高網路傳輸效率。
對於TCP頭部中的選項,需要注意以下細節:
– 選項需要遵循長度為4位元組的整數倍。因為TCP頭部中的長度是固定的,而且選項會使TCP首部變長,如果選項的長度不是4位元組的整數倍,就需要添加填充(Padding),以使總長度為4位元組的整數倍。
– 某些選項可能會被中間路由器或者應用層協議過濾,因此實際使用中需要謹慎。
六、完整代碼實現
下面是基於Python語言的TCP頭部的完整代碼實現:
import struct # 定義TCP首部結構 tcp_header = struct.Struct('! H H L L B B H H H') # 定義TCP標誌位 TCP_URG = 0b010000 TCP_ACK = 0b001000 TCP_PSH = 0b000100 TCP_RST = 0b000010 TCP_SYN = 0b000001 TCP_FIN = 0b000000 # 定義TCP首部類 class TCPHeader: def __init__(self, src_port, dst_port, seq_num, ack_num, flags, window_size): self.src_port = src_port # 源埠 self.dst_port = dst_port # 目的埠 self.seq_num = seq_num # 序列號 self.ack_num = ack_num # 確認號 self.data_offset = 5 # 數據偏移 self.reserved = 0 # 保留 self.flags = flags # 標誌位 self.window_size = window_size # 窗口大小 self.checksum = 0 # 校驗和 self.urgent_pointer = 0 # 緊急指針 self.options = bytes() # 可選項 self.padding = bytes() # 填充 # 將TCP頭部打包成二進位數據 def pack(self): data_offset = (self.data_offset << 4) | 0 flags = self.flags tcp_header_pack = tcp_header.pack( self.src_port, # 源埠 self.dst_port, # 目的埠 self.seq_num, # 序列號 self.ack_num, # 確認號 data_offset, # 數據偏移 self.reserved, # 保留 flags, # 標誌位 self.window_size, # 窗口大小 self.checksum, # 校驗和 self.urgent_pointer # 緊急指針 ) # 添加選項和填充 header = self.options + self.padding return tcp_header_pack + header
以上就是TCP首部的詳細解析及代碼實現。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/289108.html