Python-web-communicate/校验和解释.md
fly6516 71a8e81f68 docs: 添加原理解释和校验和计算文档
- 新增原理解释文档,详细说明了 ICMP、UDP 和 TCP 报文的构建与发送原理
- 新增校验和计算文档,提供了正确的 ICMP 校验和计算方法
- 这些文档有助于开发者更好地理解网络报文的构建和发送过程
2025-01-06 15:07:59 +08:00

1.7 KiB

为了正确地计算 ICMP 报文的校验和 (checksum),我们需要遵循以下步骤:

  1. 填充报文头部的校验和字段为 0
  2. 将报文数据划分为 16 位块并求和
  3. 如果报文长度为奇数,在末尾补零
  4. 对总和取反,并将其结果存入校验和字段

以下是修改后的代码,增加了正确的 ICMP 校验和计算:

# 计算校验和
def calculate_checksum(data):
    checksum = 0
    n = len(data)

    # 按 16 位块划分
    for i in range(0, n - 1, 2):
        chunk = (data[i] << 8) + data[i + 1]
        checksum += chunk

    # 如果长度为奇数,补零
    if n % 2 == 1:
        checksum += data[-1] << 8

    # 将 32 位总和折叠为 16 位
    checksum = (checksum >> 16) + (checksum & 0xFFFF)
    checksum += (checksum >> 16)

    # 对总和取反
    return ~checksum & 0xFFFF


# 构造 ICMP 报文
def construct_icmp():
    # ICMP 报文头部: 类型(8), 代码(0), 校验和(0), 标识符(1), 序列号(1)
    icmp_header = struct.pack('!BBHHH', 8, 0, 0, 1, 1)
    data = b'Ping'
    # 计算校验和
    checksum = calculate_checksum(icmp_header + data)
    # 填充校验和字段
    icmp_header = struct.pack('!BBHHH', 8, 0, checksum, 1, 1)
    return icmp_header + data

说明

  • calculate_checksum 函数负责按 ICMP 的要求计算校验和。
  • 数据部分(例如 "Ping")被添加到报文头后计算校验和。
  • 构造的 ICMP 报文将包含报文头和数据部分。

使用方法

使用这个改进后的 construct_icmp 函数可以确保生成的 ICMP 报文具有正确的校验和,从而能够在网络中正常解析和传输。