3

我不确定如何使用hton(). 理论是通过网络发送的任何数据都应该是网络字节(即大端)格式。假设客户端 A 支持大端,B 支持小端。我正在从 A 向 B 发送数据,并且数据被读取为多字节。然后在网络中,我们需要使用htonl()和将数据转换为网络字节顺序htons()。由于客户端 A 已经是大端,htonl()htons()返回相同的输出。但是 B 是 little-endian,所以这些函数颠倒了顺序。鉴于此,我们怎么能说坚持一种通用格式(即大端)是解决大端和小端机器需要通信的问题的方法呢?

4

2 回答 2

7

我会以另一种方式尝试,显示整个流程:

通过网络发送0x44332211总是发生在44 33 22 11. 发送者htonl()通过恢复字节的顺序(在 LE 机器上)或只是让它们保持原样(在 BE 机器上)来确保这一点。接收者通过恢复或离开它们再次将它们44 33 22 11变成- 。0x44332211ntohl()

提到的函数{hton,ntoh}{l,s}()有助于以可移植的方式进行编程:无论程序在 LE 或 BE 机器上运行,它们总是以应有的方式工作。因此,即使在 BE 机器上,也应该调用函数,即使它们是 noops。

例子:

A (BE) 想要发送0x44332211给 B (LE)。

  1. A0x44332211在内存中的数字为44 33 22 11
  2. A 调用htonl()程序已被编写为可移植的。
  3. 该数字仍然表示为44 33 22 11并通过网络发送。
  4. B 接收44 33 22 11并接通ntohl()
  5. B 获取由11 22 33 44from表示的值ntohl()并将其放入相应的变量中 - 然后得到0x44332211所需的结果。

同样,始终调用这些函数的需要使您不必考虑您正在为哪种机器编程 - 只需为各种机器编写程序在需要时调用这些函数中的每一个。

同样的例子可以在不知道 A 或 B 是 BE 还是 LE 的情况下表示:

  1. A 有0x44332211内存中的数字。
  2. A 调用htonl(),以便通过网络发送号码44 33 22 11。这是通过恢复还是离开来完成,由主机 B 的字节序决定。
  3. B 接收44 33 22 11并接通ntohl()。这个反转与否,取决于主机 B 的字节序。
  4. B 得到0x44332211想要的值。
于 2013-04-07T10:46:09.817 回答
1

我认为您认为客户端 B 以“相反的顺序”看到字节意味着它们是错误的。与客户端 A 相比,字节的顺序相反,但这是因为客户端 A 从客户端 B 向后解释整数;两者最终仍会将其解释为相同的数字。例如,一台机器将数字 4 表示为00 00 00 04。另一个将其表示为04 00 00 00,但两者仍将其视为 4 ——如果您将 1 添加到它,您将分别得到00 00 00 0505 00 00 00hton/函数的ntoh存在是因为无​​法查看数字并知道它是大端还是小端,因此接收者无法确定解释字节的方式

于 2013-04-07T06:38:25.620 回答