首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在python中发送带有“struct”库的IPv6地址

如何在python中发送带有“struct”库的IPv6地址
EN

Stack Overflow用户
提问于 2021-12-07 13:59:08
回答 1查看 194关注 0票数 0

我请求你的帮助,因为我已经被同样的问题困了3天了。如果我有:

Value1 = 0, Value2 = 3.10 and IPv6 = '2001::1'

我想用以下命令打包所有3个值:package = struct.pack(*format*, value1, value2, IPv6)

我的问题是:我不知道C类型的格式字符是什么格式的,我可以用它来打包IPv6并保留它的16个字节。我知道我可以用format = 'i f ?'和i作为整数/f作为浮点数,但是我需要用什么来替换'?‘它是用于打包这三个值的IPv6地址的C类型格式字符。

拜托有人能帮我吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-07 14:27:37

为此使用struct并不那么简单,因为在将IPv6地址添加到结构之前,您必须知道正确的字节值。'2001::1‘是一种文本表示法,与给出的值不太接近:您必须在:上拆分字符串,用"0“替换缺少的值,然后在结构中填充一个4 16位数字列表。当然,在IPv6字符串表示中也有一些特殊的情况和语法。

幸运的是,Python已经为您处理了。stdlib的ipaddress模块。

只需导入ipaddress,为包的第一部分格式化结构,并将其与IPv6Address Python中的“打包”属性连接起来:

代码语言:javascript
运行
复制
import struct
import ipaddress


Value1 = 0
Value2 = 3.10 
IPv6 = '2001::1'

payload = struct.pack("if", (Value1, Value2)) + ipaddress.ip_address(IPv6).packed

但是,我想知道用这种方式打包一个int和一个浮点数以及一个IP地址是否会有效--无论读取什么代码,它都将与您正在编写的代码超级耦合。如果您只是将其存储到由您控制的Python程序读取的文件中,只需使用pickle即可。如果您打算通过网络将这些值发送到非Python程序,那么传递它们的无模式文本方式(如JSON )可能要简单得多。

如果您的真的想要以紧凑的方式存储这些,而且只有这些,以节省空间,那么就有成千上万的空间,并且它们将被同一个程序读取:尝试numpy数组。它们将处理每种对象类型的紧凑二进制表示,并且可以读取并写入二进制文件,numpy将为您处理记录偏移量。

我能看到的唯一的用例是,如果您有一个不受您控制的低级别协议的程序,而该协议正是期望这种记录格式的话。由于您正在猜测如何创建有效负载,并试图将"3.10“传递为浮点值,所以情况似乎并非如此。谈到这一点,"3.10“或其他数字可能不会像这样的结构形式良好的2-十进制数值,因为浮点数是如何在内部表示的。我建议你回顾一下你的目标和需求,不要把事情搞得太复杂。

要将其解压缩,更容易的方法是使用struct仅恢复数字值,并将剩余的16个字节传回ip_address工厂函数--它会自动创建一个IPv6对象,该对象的字符串表示形式是友好的“2001:1”。

我在交互式提示符中键入“往返”:

代码语言:javascript
运行
复制
In [30]: import struct, ipaddress

In [31]: x = ipaddress.ip_address('2001::1')

In [32]: v1 = 2;v2 = 3.10

In [33]: payload = struct.pack(">if",v1, v2) + x.packed

In [34]: print(payload)
b'\x00\x00\x00\x02@Fff \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

In [35]: v3, v4, nx = struct.unpack(">if", aa[:-16]) + (ipaddress.ip_address(aa[-16:]),)

In [36]: print(v3, v4, nx)
2 3.0999999046325684 2001::1

需要注意的两件事是:在struct格式化字符串上添加了>前缀,以确保在对其内容进行编码时的字节顺序,以及如上所述的"3.10“值不会作为”好的两位小数位“值进行往返。如果需要,在表示服务器端的数字时使用round(number, 2)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70261472

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档