我不确定如何使用hton()
。理论上,通过网络发送的任何数据都应采用网络字节(即大端)格式。假设客户端A支持big-endian而B支持little-endian。我正在从A发送数据到B,数据被读取为多字节。然后在网络中,我们需要使用htonl()
和htons()
将数据转换为网络字节顺序。由于客户端A已经是big-endian,htonl()
和htons()
会返回相同的输出。但是B是小端的,所以这些功能颠倒了顺序。鉴于此,我们怎么能说当大端和小端机器需要通信时,坚持使用通用格式(即大端)是解决问题的方法?
答案 0 :(得分:7)
我会以另一种方式尝试,显示整个流程:
通过电话发送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)。
0x44332211
为44 33 22 11
。htonl()
,因为该程序已被编写为可移植。44 33 22 11
并通过电汇发送。44 33 22 11
并通过ntohl()
。11 22 33 44
获取ntohl()
所代表的值,并将其放入相应的变量中,然后根据需要生成0x44332211
。同样,总是调用这些函数的需求使您无需考虑编写哪种类型的机器 - 只需编程所有种类的机器,并在需要时调用这些机器中的每一种
可以在不知道A或B是BE还是LE的情况下表达相同的示例:
0x44332211
。htonl()
,以便号码通过网络发送为44 33 22 11
。
是通过还原还是通过保留来完成,取决于主机B的字节顺序。44 33 22 11
并将其通过ntohl()
。这个是否反转,取决于主机B的字节顺序。0x44332211
。答案 1 :(得分:1)
我认为你认为客户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
函数,因为无法查看数字并知道它是大端还是小端,因此接收器无法确定解释字节的方式