我不确定如何使用hton()
. 理论是通过网络发送的任何数据都应该是网络字节(即大端)格式。假设客户端 A 支持大端,B 支持小端。我正在从 A 向 B 发送数据,并且数据被读取为多字节。然后在网络中,我们需要使用htonl()
和将数据转换为网络字节顺序htons()
。由于客户端 A 已经是大端,htonl()
并htons()
返回相同的输出。但是 B 是 little-endian,所以这些函数颠倒了顺序。鉴于此,我们怎么能说坚持一种通用格式(即大端)是解决大端和小端机器需要通信的问题的方法呢?
2 回答
我会以另一种方式尝试,显示整个流程:
通过网络发送0x44332211
总是发生在44 33 22 11
. 发送者htonl()
通过恢复字节的顺序(在 LE 机器上)或只是让它们保持原样(在 BE 机器上)来确保这一点。接收者通过恢复或离开它们再次将它们44 33 22 11
变成- 。0x44332211
ntohl()
提到的函数{hton,ntoh}{l,s}()
有助于以可移植的方式进行编程:无论程序在 LE 或 BE 机器上运行,它们总是以应有的方式工作。因此,即使在 BE 机器上,也应该调用函数,即使它们是 noops。
例子:
A (BE) 想要发送0x44332211
给 B (LE)。
- A
0x44332211
在内存中的数字为44 33 22 11
。 - A 调用
htonl()
程序已被编写为可移植的。 - 该数字仍然表示为
44 33 22 11
并通过网络发送。 - B 接收
44 33 22 11
并接通ntohl()
。 - B 获取由
11 22 33 44
from表示的值ntohl()
并将其放入相应的变量中 - 然后得到0x44332211
所需的结果。
同样,始终调用这些函数的需要使您不必考虑您正在为哪种机器编程 - 只需为各种机器编写程序并在需要时调用这些函数中的每一个。
同样的例子可以在不知道 A 或 B 是 BE 还是 LE 的情况下表示:
- A 有
0x44332211
内存中的数字。 - A 调用
htonl()
,以便通过网络发送号码44 33 22 11
。这是通过恢复还是离开来完成,由主机 B 的字节序决定。 - B 接收
44 33 22 11
并接通ntohl()
。这个反转与否,取决于主机 B 的字节序。 - B 得到
0x44332211
想要的值。
我认为您认为客户端 B 以“相反的顺序”看到字节意味着它们是错误的。与客户端 A 相比,字节的顺序相反,但这是因为客户端 A 从客户端 B 向后解释整数;两者最终仍会将其解释为相同的数字。例如,一台机器将数字 4 表示为00 00 00 04
。另一个将其表示为04 00 00 00
,但两者仍将其视为 4 ——如果您将 1 添加到它,您将分别得到00 00 00 05
和05 00 00 00
。hton
/函数的ntoh
存在是因为无法查看数字并知道它是大端还是小端,因此接收者无法确定解释字节的方式