2

我想使用 python 创建一个数据包。数据包有 4 个字段,每个字段 32 位。我有示例代码:

import socket, sys, os, struct
field1 = 1
field2 = '255.255.255.0'
field3 = 20
field4 = '192.168.0.1'

struct.pack=('!L4sL4s',field1,field2,field3)

但我没有输出。如何格式化此数据包,以便每个变量可以有 4 个字节。

4

4 回答 4

4
>>> struct.pack('!L4sL4s', field1, socket.inet_aton(field2),
                           field3, socket.inet_aton(field4))
'\x00\x00\x00\x01\xff\xff\xff\x00\x00\x00\x00\x14\xc0\xa8\x00\x01'
于 2013-02-18T03:27:45.343 回答
3

您将元组分配('!L4sL4s',field1,field2,field3)struct.pack. 你需要这样调用struct.pack:(struct.pack('!L4sL4s',field1,field2,field3,field4)没有=符号)。

于 2013-02-18T03:11:29.613 回答
0

调用的结果将pack返回给您,您可以将其分配给变量。您的行应如下所示:

my_packet = struct.pack('!L4sL4s',field1,field2,field3)

请注意,此行需要一个 unsigned long int,然后是长度为 4 的字符串,然后是 long int,然后是长度为 4 的字符串。field2并且field4都比这长。例如,尝试使用len(field2)看看它有多长!

于 2013-02-18T03:13:08.810 回答
0

您正在对打包字符串和整数进行奇怪的组合。您可以将字符串打包为无符号整数,如下所示:

>>> import struct
>>> field2 = '255.255.255.0'
>>> struct.pack('4B',*tuple(int(x) for x in field2.split('.')))
'\xff\xff\xff\x00'

考虑到这一点,您可能想要做的是:

from itertools import chain
f2_int = map(int,field2.split('.'))
f4_int = map(int,field4.split('.'))
struct.pack('L4BL4B',*chain([field1],f2_int,[field3],f4_int))

演示:

>>> import struct
>>> field1 = 1
>>> field2 = '255.255.255.0'
>>> field3 = 20
>>> field4 = '192.168.0.1'
>>> from itertools import chain
>>> f2_int = map(int,field2.split('.'))
>>> f4_int = map(int,field4.split('.'))
>>> struct.pack('L4BL4B',*chain([field1],f2_int,[field3],f4_int))
'\x01\x00\x00\x00\xff\xff\xff\x00\x14\x00\x00\x00\xc0\xa8\x00\x01'

事实证明,我可能在这里重新发明轮子。此外,您可能想检查一下socket.inet_aton,它看起来像您所说的那样将您的 IP 地址正确地打包成 32 位。

于 2013-02-18T03:17:06.850 回答