网络提交转换为bigendian的正确方法

迈克尔

我需要通过网络获得一个int。这是在 big-endian 中转换为字节的正确方法吗?

pack("I",socket.htonl(integer_value))

我将其解压缩为:

socket.ntohl(unpack("I",data)[0])

我注意到 pack-unpack 也有 <> 用于字节序转换,所以我不确定我是否可以直接使用它,或者 htonl 是否更安全。

吉尔·汉密尔顿

您应该使用struct模块与另一个系统进行通信。通过使用第htonl一个,您最终会得到一个不确定的传输顺序。

由于您需要将整数转换为字节字符串才能将其发送到另一个系统,因此您需要使用struct.pack(因为htonl只返回一个与作为参数传递的整数不同的整数,并且您不能直接发送整数)。并且在使用时,struct.pack您必须为该字节串选择一个字节序(如果您不指定一个字节序,您将获得一个默认排序,该排序在接收端可能不同,因此您确实需要选择一个)。

将整数转换为确定顺序的字节序列正是这样struct.pack("!I", integer_value)做的,而确定顺序的字节序列正是您在接收端所需要的。

另一方面,如果您使用struct.pack("!I", socket.htonl(integer_value)),那有什么作用?好吧,首先它将整数放入 big-endian 顺序(网络字节顺序),然​​后将您已经使用的 big-endian 整数转换为“big-endian order”中的字节。但是,在小端机器上,这实际上会再次颠倒顺序,如果您同时执行这两个操作,您最终将以小端字节顺序传输整数。

但是在大端机器上htonl是无操作的,然后您将结果按大端顺序转换为字节。

因此,使用ntohl实际上违背了目的,接收机器必须知道发送机器上使用的字节顺序才能正确解码。观察...

小端盒:

>>> print(socket.htonl(27))
452984832
>>> print(struct.pack("!I", 27))
b'\x00\x00\x00\x1b'
>>> print(struct.pack("!I", socket.htonl(27)))
b'\x1b\x00\x00\x00'

大端盒:

>>> print(socket.htonl(27))
27
>>> print(struct.pack("!I", 27))
b'\x00\x00\x00\x1b'
>>> print(struct.pack("!I", socket.htonl(27)))
b'\x00\x00\x00\x1b'

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章