文章目录

  • 一、TCP首部解析器的实现
  • 二、测试逻辑



       上一节解析了

IP首部报文后,本节继续解析TCP报文首部。TCP协议处于OSI七层模型的传输层,传输层的作用就是负责管理端到端的通信连接问题。连续ARQ(automatic repeat request 自动重传请求)协议使得的TCP协议成为一种可靠性传输的协议,滑动窗口和慢启动、拥塞避免算法又赋予了TCP协议较好的流量控制和拥塞控制,这也使得TCP协议被广泛应用在一些准确性要求相对高的场所。

一、TCP首部解析器的实现

       创建trans包 新建parser.py文件
       TCP首部位于IP首部之后,每行同为32位,总共5行,长度为20字节,也就是位于IP数据报第21-40字节的位置。
       在TCPParser中分别对头部报文的每一行进行解析。

class TransParser:

    IP_HEADER_LENGTH = 20  # IP报文头部的长度
    UDP_HEADER_LENGTH = 8  # UDP头部的长度
    TCP_HEADER_LENGTH = 20  # TCP头部的长度
    

class TCPParser(TransParser):

    @classmethod
    def parse_tcp_header(cls, tcp_header):
        """
        TCP报文格式
        1. 16位源端口号 16位目的端口号
        2. 32位序列号
        3. 32位确认号
        4. 4位数据偏移 6位保留字段 6位TCP标记 16位窗口
        5. 16位校验和 16位紧急指针
        :param tcp_header:
        :return:
        """
        line1 = struct.unpack('>HH', tcp_header[:4])
        src_port = line1[0]
        dst_port = line1[1]
        line2 = struct.unpack('>L', tcp_header[4:8])
        seq_num = line2[0]
        line3 = struct.unpack('>L', tcp_header[8:12])
        ack_num = line3[0]
        line4 = struct.unpack('>BBH', tcp_header[12:16])  # 先按照8位、8位、16位解析
        data_offset = line4[0] >> 4  # 第一个8位右移四位获取高四位
        flags = line4[1] & int(b'00111111', 2)  # 第二个八位与00111111进行与运算获取低六位
        FIN = flags & 1
        SYN = (flags >> 1) & 1
        RST = (flags >> 2) & 1
        PSH = (flags >> 3) & 1
        ACK = (flags >> 4) & 1
        URG = (flags >> 5) & 1
        win_size = line4[2]
        line5 = struct.unpack('>HH', tcp_header[16:20])
        tcp_checksum = line5[0]
        urg_pointer = line5[1]

        # 返回结果
        # src_port 源端口
        # dst_port 目的端口
        # seq_num 序列号
        # ack_num 确认号
        # data_offset 数据偏移量
        # flags 标志位
        #     FIN 结束位
        #     SYN 同步位
        #     RST 重启位
        #     PSH 推送位
        #     ACK 确认位
        #     URG 紧急位
        # win_size 窗口大小
        # tcp_checksum TCP校验和
        # urg_pointer 紧急指针
        return {
            'src_port': src_port,
            'dst_port': dst_port,
            'seq_num': seq_num,
            'ack_num': ack_num,
            'data_offset': data_offset,
            'flags': {
                'FIN': FIN,
                'SYN': SYN,
                'RST': RST,
                'PSH': PSH,
                'ACK': ACK,
                'URG': URG
            },
            'win_size': win_size,
            'tcp_checksum': tcp_checksum,
            'urg_pointer': urg_pointer
        }

    @classmethod
    def parser(cls, packet):
        
        return cls.parse_tcp_header(packet[cls.IP_HEADER_LENGTH:cls.IP_HEADER_LENGTH + cls.TCP_HEADER_LENGTH])

二、测试逻辑

       当IP首部中的protocol等于6时表示该报文属于TCP协议,在ServerProcessTask中调用TCPParser。

def process(self):
    """
    异步处理方法
    :return:
    """
    headers = {
        'network_header': None,
        'transport_header': None
    }

    ip_header = IPParser.parse(self.packet)
    headers['network_header'] = ip_header
    if ip_header['protocol'] == 6:
        headers['transport_header'] = TCPParser.parser(self.packet)

    return headers

       测试结果:

python解析tcp端口代码 python解析tcp报文_python解析tcp端口代码