来自socket()的UDP数据包头与预期不符

5
我正在构建一个UDP服务器来解析和验证接收到的UDP数据包。我已经能够接收和解析数据包,但头部值不是我期望的值。
以下是接收数据包的结构:
数据包ID(4个字节) 数据包序列(4个字节) XOR密钥(2个字节) 数据包中校验和数量(2个字节) 循环校验CRC32(可变)
要发送数据包,请:
with open('payloadfile.bin') as op:
    payload = pickle.load(op)

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

for i in payload:
    sock.sentto(payload, ('127.0.0.1',4545))

接收并解析此数据包。
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind('127.0.0.1',4545)

while 1:
    packet = sock.recvfrom(65565)
    packet = packet[0]

    # parse IP
    ip_header = packet[0:20]
    iph = struct.unpack('!BBHHHBBH4s4s' , ip_header)

    #all the following values are incorrect
    version_ihl = iph[0]
    version = version_ihl >> 4
    ihl = version_ihl & 0xF

    ttl = iph[5]
    protocol = iph[6]
    s_addr = socket.inet_ntoa(iph[8]);
    d_addr = socket.inet_ntoa(iph[9]);

    # parse UDP
    packet = packet[20:28]
    data = packet[header_length:]
    source_port, dest_port, data_length, checksum = struct.unpack("!HHHH", header)

据我目前的理解,这应该是一般的结构
IP_HEADER ( UDP_HEADER ( PAYLOAD )))

我想正确解析头部,然后提取有效载荷。


1
你只能获取数据报有效负载,而无法获取IP/UDP头部信息...这是有意为之的。你恰好以IP4/UDP方式打开了此套接字,但socket是一个通用接口,可与多种传输协议一起使用。例如,它应该可以透明地与IP6甚至(天哪!)IPX一起工作。 - tdelaney
1个回答

6

不幸的是,标准套接字接口无法让你访问数据帧,也无法包括来自传输层的IP数据报头或TCP/UDP头。

要获取较低级别的数据,你必须使用所谓的原始套接字接口,其中Windows尝试阻止您使用,因为您可能是黑客。 这篇文章可以给你一些线索。


我想我会称之为“幸运”,因为它是一个通用接口...但除此之外,我喜欢你的回答! - tdelaney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接