使用struct.pack在Python中创建数据包
我想用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 个回答
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位,正如你所说的那样。
3
你正在把一个元组 ('!L4sL4s',field1,field2,field3)
传给 struct.pack
。你需要这样调用 struct.pack
:struct.pack('!L4sL4s',field1,field2,field3,field4)
(注意没有等号)。
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'