我在little endian[le]机器[linux,intel处理器]上运行了以下程序。我无法解释下面代码片段中的3个输出。因为machine是le,所以a的值存储为0x78563412。打印时,显示其实际值。因为它是一个le机器,我希望ntohl()是一个no-op和display0x78563412,它正在这样做。但是,我希望包含0x12345678的第二个print语句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;
}

输出:
Original - 0x12345678
Network - 0x78563412
Host - 0x78563412

最佳答案

因为它是一台机器,所以我希望ntohl()是一个禁止操作的机器
这就是错误。网络字节顺序为大端,主机字节顺序为小端。因此,ntohlhtonl都返回其输入的字节交换版本。
记住,htonl的要点是可以在主机上取一个整数,然后写入:

int i = htonl(a);

结果是,当使用网络字节顺序解释时,i的内存具有与a相同的值。因此,如果您将i的对象表示形式写入套接字,而另一端的读取器需要网络字节顺序的4字节整数,那么它将读取a的值。
显示0x78563412
这就是你要写的吗?如果ntohl是一个no op(或者更确切地说,是一个identity函数),那么您的第三行必然会打印与第一行相同的内容,因为您将拥有ntohl(a) == a。这就是big-endian实现中发生的情况,您的程序在其中打印:
Original - 0x12345678
Network - 0x12345678
Host - 0x12345678

10-07 18:43