您的位置:

TCP报文格式详解

一、TCP协议简介

TCP是传输控制协议(Transmission Control Protocol)的缩写,是互联网协议TCP/IP协议簇的一部分,是一种面向连接的、可靠的、基于字节流的传输层通信协议。

二、TCP报文格式介绍

TCP报文是TCP协议在数据传输过程中对数据的封装,由TCP头和数据两部分组成。TCP头包含20个字节的固定头部和可选的额外头部,具体格式如下:

    0       1       2       3       4       5       6       7       
     +-------+-------+-------+-------+-------+-------+-------+-------+
   0 |                     Source Address                              |
     +-------+-------+-------+-------+-------+-------+-------+-------+
   4 |                   Destination Address                           |
     +-------+-------+-------+-------+-------+-------+-------+-------+
   8 |  zeroes   |  Protocol |              TCP Length                |
     +-------+-------+-------+-------+-------+-------+-------+-------+
  12 |                        Source Port                              |
     +-------+-------+-------+-------+-------+-------+-------+-------+
  16 |                     Destination Port                            |
     +-------+-------+-------+-------+-------+-------+-------+-------+
  20 |                        Sequence Number                           |
     +-------+-------+-------+-------+-------+-------+-------+-------+
  24 |                     Acknowledgment Number                        |
     +-------+-------+-------+-------+-------+-------+-------+-------+
  28 |Hlen | Reserved  |U|A|P|R|S|F|            Window                 |
     +-------+-------+-------+-------+-------+-------+-------+-------+
  32 |           Checksum                 |         Urgent Pointer       |
     +-------+-------+-------+-------+-------+-------+-------+-------+
  36 |                    Options                    |    Padding    |
     +-------+-------+-------+-------+-------+-------+-------+-------+
  36+n|                   Data                                      |
     +-------+-------+-------+-------+-------+-------+-------+-------+

三、TCP报文格式字段详解

1. 源地址(Source Address)和目标地址(Destination Address)

源地址和目标地址字段分别占用了4个字节,分别表示源IP地址和目标IP地址,用于在网络中唯一标识数据包的源和目的。

2. 零填充(Zeroes)

4个二进制位全为0,用于对齐,保证头部的长度是32位的整数倍。

3. 协议(Protocol)

1个字节,表示上层协议,TCP协议为6。

4. TCP长度(TCP Length)

2个字节,表示整个TCP报文的长度,包含头部和数据部分。

5. 源端口号(Source Port)和目标端口号(Destination Port)

2个字节,分别表示源端口号和目标端口号,用于在主机中唯一标识对应的进程或应用程序。

6. 序列号(Sequence Number)

4个字节,表示一个占用4个字节的序列号,用于在传输的数据中标识每个字节的顺序。

7. 确认号(Acknowledgment Number)

4个字节,表示期望接收到的下一个字节的序列号,用于TCP的可靠性控制。

8. HLEN(Header Length)

4个比特位,表示TCP头部的长度,最多可以有60字节的头部。

9. 保留位(Reserved)

为3个比特位,保留未来使用,取值均为0。

10. 标识位(UAPRSF)

每个标识位都是一个比特位:

  • URG:紧急指针是否有效,1表示有效,0表示无效。
  • ACK:确认序号是否有效,1表示有效,0表示无效。
  • PSH:是否立即传输数据,1表示立即传输,0表示缓存。
  • RST:是否复位连接,1表示复位,0表示未复位。
  • SYN:是否为同步请求包,1表示同步请求包,0表示正常数据包。
  • FIN:是否为结束连接包,1表示结束连接包,0表示正常数据包。

11. 窗口大小(Window)

2个字节,表示接收端可以接收的数据大小,用于流量控制。

12. 校验和(Checksum)

2个字节,对TCP头部进行校验的结果,用于检测数据是否正确。校验和的计算方法包括TCP头部和数据部分。

13. 紧急指针(Urgent Pointer)

2个字节,只有当URG标识位为1时,才能有紧急指针,表示紧急数据的位置。

14. 选项(Options)

可选字段,不定长,最长可达40字节。可以包含多个选项,使用一个字节的类型字段和一个字节的长度字段来表示每个选项的类型和长度,并按照顺序排列。

四、TCP报文格式代码示例

下面是一个基于Python的TCP报文格式代码示例:

import struct

# 自定义TCP头部结构体
class TCPHeader:
    def __init__(self, source_port, dest_port, seq_num, ack_num, data_offset, 
                 flags, window, checksum, urgent_ptr, options):
        self.source_port = source_port
        self.dest_port = dest_port
        self.seq_num = seq_num
        self.ack_num = ack_num
        self.data_offset = data_offset
        self.flags = flags
        self.window = window
        self.checksum = checksum
        self.urgent_ptr = urgent_ptr
        self.options = options

    # 打包成二进制TCP头部数据
    def pack(self):
        data_offset = self.data_offset << 4
        flags = self.flags & 0b111111
        tcp_hdr = struct.pack('!HHLLBBHHH', self.source_port, self.dest_port,
                              self.seq_num, self.ack_num, data_offset, flags,
                              self.window, self.checksum, self.urgent_ptr)
        return tcp_hdr + self.options.encode()

# 构造TCP报文
tcp_hdr = TCPHeader(12345, 80, 0, 0, 5, 0b101010, 4096, 0, 0, 'MSS: 1460')
tcp_pkt = tcp_hdr.pack()

print(tcp_pkt)