【问题标题】:ntohl() vs htonl() in Little EndianLittle Endian 中的 ntohl() 与 htonl()
【发布时间】:2013-03-29 15:07:40
【问题描述】:

请澄清我的疑问,因为我对以下内容感到非常困惑,我无法得到 清除网络上其他任何地方的 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) => 我正在将小端(LE)转换为BE。所以输出将是0x11223344。我明白了。我的问题是ntoh()。现在ntohl(0x44332211) => 什么?

在这里,我在 1 个终端上执行这两个命令。所以主机到网络,即hton() 表示我的终端到网络。这就说得通了。但是这里ntohl() 是什么意思?如果我们有ntohl(),就会出现:

a PC A----(ie hton)sending data over network------>(ie ntoh) to PC B?

另外ntoh 需要一个网络字节顺序,即大端。请解释上面的ntohl() 是什么意思,为什么它的打印与0x11223344 相同,为什么不是0x44332211

【问题讨论】:

    标签: c endianness htonl


    【解决方案1】:

    假设您的程序在 little-endian 机器(例如 x86)上运行,ntohl(a) 将返回 0x11223344(即它会翻转 0x11223344 值的字节顺序,就像 htonl() 一样)。

    另一方面,如果您的程序在大端机器(例如 PowerPC Mac)上运行,则 ntohl(a) 和 htonl(a) 都将逐字返回 a,因为机器的内部/主机格式已经和网络格式一样了。

    还有(至少理论上)您的程序运行在某些unusual hardware 上的可能性,该unusual hardware 使用既不是大端也不是小端的数字表示。在这种情况下,该环境的 htonl() 和 ntohl() 函数将被编程为做正确的事情(无论可能是什么)以将该机器的内部表示转换为标准网络表示(即大端)和返回。

    这些函数的预期使用模式是这样的:

    • 每当您要向网络发送一个 long 时,请在其上调用 htonl() 并发送该值。
    • 只要您刚刚从网络收到一个 long,就调用它的 ntohl() 并改用该值。

    这样,主机的数字表示和网络/大端表示之间的任何差异都会在 htonl() 和 ntohl() 中自动为您处理,您不必担心编写(和测试!)为您的程序可能在其上运行的每种计算机体系结构提供单独的转换代码。

    【讨论】:

      【解决方案2】:

      偶然发现了这篇文章。我同意杰里米的回答,但只想再补充一点: 如有疑问,请转到源代码。如果您查看 GCC 库中的 ntoh() 和 hton() 定义:

      netinet/in.h>

      #  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 数据上调用这两个宏,这就是问题所在。

      我想我迟到了。但是,我希望下一位访问者会发现这个答案很有用:)

      【讨论】:

        猜你喜欢
        • 2020-12-01
        • 2016-08-23
        • 1970-01-01
        • 2018-05-15
        • 2019-06-30
        • 2014-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多