请澄清我的疑问,因为我对下面的东西感到困惑,我无法得到一个 在网上的任何其他地方清理anwser。
#include<stdio.h>
int main()
{
int a = 0x44332211;
printf("Network - 0x%x\n", htonl(a));// Host to network
printf("Host - 0x%x\n", ntohl(a));// Network to host
return 0;
}
输出:
Network - 0x11223344
Host - 0x11223344
此处htonl(0x44332211)
=&gt;我正在将小端(LE)转换为BE。因此输出将为0x11223344
。我明白了。我的问题在于ntoh()
。现在ntohl(0x44332211)
=&gt;什么?
这里我正在1终端上执行两个命令。所以托管到网络,即hton()
意味着我的网络终端。那讲得通。但这里ntohl()
意味着什么?如果我们有:{/ p>,ntohl()
就会出现
a PC A----(ie hton)sending data over network------>(ie ntoh) to PC B?
同样ntoh
期望网络字节顺序,即大端。请注意上面ntohl()
的含义以及为什么它与0x11223344
打印相同,为什么不打0x44332211
?
答案 0 :(得分:11)
假设您的程序在小端机器上运行(例如x86),ntohl(a)将返回0x11223344(即它将翻转0x11223344值的字节顺序,就像htonl()一样)。
另一方面,如果你的程序在大端机器(例如PowerPC Mac)上运行,那么ntohl(a)和htonl(a)都将返回a,逐字,因为机器的内部/主机格式已经与网络格式相同。
还有一种(至少理论上的)可能性,你的程序运行在一些unusual hardware上,它使用的数字表示既不是big-endian也不是little-endian。在这种情况下,该环境的htonl()和ntohl()函数将被编程为执行正确的操作(无论可能是什么)将该机器的内部表示转换为标准网络表示(这是大端)和回来。
这些功能的预期使用模式是:
这样,主机计算机的数字表示和网络/大端表示之间的任何差异都会在htonl()和ntohl()内自动处理,你不必担心写(和测试!)为您的程序可能运行的每个计算机体系结构单独的转换代码。
答案 1 :(得分:9)
偶然发现了这篇文章。我同意Jeremy的回答,但只是想补充一点: 如有疑问,请转到源代码。如果你看一下GCC库中的ntoh()和hton()定义:
&LT; netinet/in.h&GT;
# if __BYTE_ORDER == __LITTLE_ENDIAN
#define ntohl(x) __bswap_32 (x)
#define htonl(x) __bswap_32 (x)
#endif
因此,ntohl()和htonl()都只是byteswap.h中定义的字节交换。这就是为什么这两个宏的输出相同的原因。
现在,他们为什么一样? 好吧,作者希望在网络端数据(通常是接收数据包缓冲区的内容)上调用ntohl(),类似地,在主机端数据(主机写入的数据)上调用htonl()。
在您的情况下,您在相同的Host Endian数据上调用这两个宏,这就是问题所在。
猜猜我迟到了回复。但是,我希望下一位访客发现这个答案很有用:)