0

我使用 python 套接字发送 DNS 查询数据包套接字并监听响应。socket.recvfrom(2048)最后,我按预期得到了函数的DNS响应包。但奇怪的是,我将响应数据包与 Wireshark 抓取的数据包进行比较,发现存在很多差异。

3f在第二张图片中会发现差异。

Wireshark爬取的DNS响应包(高亮部分)

收到的DNS响应包socket.recvfrom(2048)

创建插座零件代码:

    ipv = check_ip(dst)
    udp = socket.getprotobyname(Proto.UDP)
    if ipv == IPV.ERROR:
        return None
    elif ipv == IPV.IPV4:
        return socket.socket(socket.AF_INET, socket.SOCK_DGRAM, udp)
    elif ipv == IPV.IPV6:
        return socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, udp)
    else:
        return None

接收 DNS 响应数据包部分代码:

    remained_time = 0
    while True:
        remained_time = self.timeout - timeit.default_timer() + sent_time
        readable = select.select([sock], [], [], remained_time)[0]
        if len(readable) == 0:
            return (-1, None)

        packet, addr = sock.recvfrom(4096)
4

1 回答 1

2

字节0x3F是 ASCII'?'字符。这通常意味着数据被视为文本并通过不支持正在转换的字节的字符集转换。

请注意,0x3F它仅替换 > 0x7F(ASCII 支持的最后一个字节)的字节。范围内的非 ASCII 字节0x80-0xFF受字符集解释的影响。

这是有道理的,因为您使用的recvfrom()是返回 a的版本string,因此需要将接收到的字节转换为 Python 的默认string编码。

由于您需要原始字节,因此请recvfrom_into()用于填充预分配的bytearray,例如:

packet = bytearray(4096)
remained_time = 0
while True:
    remained_time = self.timeout - timeit.default_timer() + sent_time
    readable = select.select([sock], [], [], remained_time)[0]
    if len(readable) == 0:
        return (-1, None)
    nbytes, addr = sock.recvfrom_into(packet)

然后,您可以根据需要使用packet最多nbytes字节数。

于 2018-09-12T07:05:50.783 回答