htonl()和ntohl()对整数的输出相同

Bha*_*kar 11 c endianness

我在little-endian [LE]机器[Linux,Intel处理器]上运行了以下程序.我无法在下面的代码片段中解释3个输出.由于机器是LE,因此值a存储为0x78563412.打印时,它显示其实际值.由于它是LE机器,我希望ntohl()它是一个无操作和显示器0x78563412,它正在做.但是,我希望0x12345678第二个打印声明包含htonl().有人可以帮我理解他们为什么一样吗?

int main() 
{
    int a = 0x12345678; 

    printf("Original - 0x%x\n", (a)); 
    printf("Network - 0x%x\n", htonl(a)); 
    printf("Host - 0x%x\n", ntohl(a)); 

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

Original - 0x12345678
Network - 0x78563412
Host - 0x78563412
Run Code Online (Sandbox Code Playgroud)

Ste*_*sop 23

由于它是LE机器,我希望ntohl()是一个无操作

那是错误的.网络字节顺序为big-endian,主机字节顺序为little-endian.因此,无论是ntohlhtonl返回其输入的字节交换版本.

记住,关键htonl是你可以在主机上取一个整数,然后写:

int i = htonl(a);
Run Code Online (Sandbox Code Playgroud)

结果是i,当使用网络字节顺序解释时,内存具有相同的值a.因此,如果您将对象表示写入i套接字并且另一端的读取器需要网络字节顺序中的4字节整数,则它将读取值的值a.

和显示 0x78563412

这是你打算写的吗?如果ntohl是无操作(或者更确切地说是身份功能),那么你的第三行必然会打印出与你的第一行相同的东西,因为你会有ntohl(a) == a.这是在big-endian实现上发生的事情,程序打印:

Original - 0x12345678
Network - 0x12345678
Host - 0x12345678
Run Code Online (Sandbox Code Playgroud)

  • @Bhaskar:Brian Roach的观点也很重要,那么:你从未计算过`htonl(ntohl(a))`.你计算了`htonl(a)`和`ntohl(a)`. (2认同)

Alo*_*hal 12

htonl并且ntohl功能完全相同.他们应该满足htonl(ntohl(x)) == x.它们的命名方式不同仅适用于文档(您明确指出要从主机到网络或其他方式进行转换,即使它们是相同的).因此,在小端机器上,它们都执行字节交换,而在大端机器上,它们都是无操作的.

  • 在一个假设的"愚蠢的结尾"C实现中,字节既不是大端(有序的`4321`)也不是小端(有序的'1234`),而是命令例如`3214`,你仍然会有`htonl( ntohl(x))`,但是`htonl`和`ntohl`不会做同样的事情,它们是相反方向的8位旋转.我希望不存在这样的架构,但它可以实现套接字API,因为`htonl`和`ntohl`是单独的函数. (7认同)
  • @SteveJessop 你当然是对的。这可能是我们有两个不同功能的*真正*原因。http://en.wikipedia.org/wiki/Endianness#Middle-endian (2认同)
  • @Steve:喜欢"愚蠢的结尾"这个名字.:-) (2认同)

Bri*_*ach 5

因为您正在通过a值传递,因此它们不会被这些函数中的任何一个更改.

你正在打印什么htonl()ntohl()正在返回.

编辑添加:我错过了你认为一个无操作的地方.不是.两者都将在LE机器上做同样的事情; 反转字节排序.ntohl()期待你传递一个有序的网络字节int