我需要通过网络获得一个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] 删除。
我来说两句