我不确定如何使用 hton()
。从理论上讲,通过网络发送的任何数据都应采用网络字节(即大端)格式。假设客户端A支持大端,B支持小端。我正在将数据从 A 发送到 B,并且数据被读取为多字节。然后在网络中我们需要使用htonl()
和htons()
将数据转换为网络字节序。由于客户端 A 已经是 big-endian,htonl()
和 htons()
返回相同的输出。但是 B 是小端,所以这些函数颠倒了顺序。鉴于此,当大端和小端机器需要通信时,我们怎么能说遵守通用格式(即大端)是解决问题的方法?
最佳答案
我会用另一种方式来尝试,展示整个流程:
通过网络发送 0x44332211
总是发生为 44 33 22 11
。发件人的 htonl()
通过恢复字节的顺序(在 LE 机器上)或让它们保持原样(在 BE 机器上)来确保这一点。接收方使用 ntohl()
将 44 33 22 11
转换为 0x44332211
- 同样,通过恢复或保留它们。
提到的函数 {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 从
ntohl()
中获取由11 22 33 44
表示的值,并将其放入相应的变量中 - 然后结果为0x44332211
根据需要。
同样,始终调用这些函数的需要使您无需考虑要为哪种机器编程 - 只需为所有类型的机器编程并在需要时调用这些函数中的每一个.
同样的例子可以在不知道 A 或 B 是 BE 还是 LE 的情况下表达:
- A 在内存中有编号
0x44332211
。 - A 调用
htonl()
,以便通过网络将号码作为44 33 22 11
发送。 这是通过还原还是通过离开来完成的,由主机 B 的字节顺序决定。 - B 收到
44 33 22 11
并通过ntohl()
将其放入。这个是否反转,取决于主机 B 的字节顺序。 - B 根据需要获取值
0x44332211
。
关于c - 为什么通过网络发送的数据会转换为网络字节序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15859649/