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

Posted

技术标签:

【中文标题】来自 socket() 的 UDP 数据包标头与预期不符【英文标题】:UDP packet headers from socket() are not as expected 【发布时间】:2017-02-11 16:41:17 【问题描述】:

我正在构建一个 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)))

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

【问题讨论】:

你没有得到 IP/UDP 报头,只有数据报有效负载......这是故意完成的。您碰巧将此套接字打开为 IP4/UDP,但 socket 是一个适用于多种传输协议的通用接口。例如,它应该透明地使用 IP6 甚至(我的天哪!)IPX。 【参考方案1】:

不幸的是,标准套接字接口不允许您访问数据到达的数据帧,它既不包括 IP 数据报标头,也不包括来自传输层的 TCP/UDP 标头。

要获取较低级别的数据,您必须使用所谓的原始套接字接口,Windows 试图阻止您使用,因为您可能是一名黑客。 This article 可能会给你一些线索。

【讨论】:

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

以上是关于来自 socket() 的 UDP 数据包标头与预期不符的主要内容,如果未能解决你的问题,请参考以下文章

UDP Socket:一个现有的连接被远程主机强行关闭

如何中断阻塞调用UDP socket的receive()[重复]

c#,socket无法接收分片的UDP数据包

无法使用/ AsyncUdp Socket 在 Iphone 上接收 UDP 数据包

C#中UDP(Socket)

UDP 协议 C# UdpClient乱序接收数据包丢失的问题 Socket ReceiveBufferSize