为什么 inet_ntoa 和 inet_ntop "reverse" 字节?
Why do inet_ntoa and inet_ntop "reverse" the bytes?
这是一个相当基本的问题,令我惊讶的是,我今天遇到了一个问题。
在我看来 inet_pton 和 inet_ntoa 正在颠倒给定的 IP 地址的字节:
DWORD IP;
inet_pton(AF_INET, "192.168.0.1", &IP);
printf("%08X\n", IP);
这将打印 0100A8C0
。好吧,如果我们分解字节,它是
01.00.A8.C0 = 1.0.168.192
.
同样:
IP = 0x7F000001;
struct in_addr ia;
ia.S_un.S_addr = IP;
printf("%s\n", inet_ntoa(ia));
给我 1.0.0.127
.
首先想到的是字节顺序,但是我看了MSDN文档(1 and 2),并没有提到字节顺序;这些函数会在没有明确说明的情况下任意决定使用其中一种符号,这对我来说似乎很奇怪。
这是怎么回事?
字节顺序是原因。
这些函数的重点不是生成 "readable" 整数,而是设置一个 32 位数量,准备好通过网络发送出去。 IPv4 需要 big-endian 排序,所以我敢打赌,如果你这样做 printf("%02X\n", ((char *)&IP)[0]));
,你会得到 C0
.
大于一个字节的数量(短整数、整数等)必须按照 Internet 标准要求的网络字节顺序离开线路,默认情况下是大端。
所以这些函数,如 inet_pton
、inet_ntoa
、htons
、htonl
和其他类似函数负责根据字节顺序交换这些数量的字节主持人。另一方面,接收方应使用相应的函数将网络字节顺序转换为正确的字节顺序。
这是一个相当基本的问题,令我惊讶的是,我今天遇到了一个问题。
在我看来 inet_pton 和 inet_ntoa 正在颠倒给定的 IP 地址的字节:
DWORD IP;
inet_pton(AF_INET, "192.168.0.1", &IP);
printf("%08X\n", IP);
这将打印 0100A8C0
。好吧,如果我们分解字节,它是
01.00.A8.C0 = 1.0.168.192
.
同样:
IP = 0x7F000001;
struct in_addr ia;
ia.S_un.S_addr = IP;
printf("%s\n", inet_ntoa(ia));
给我 1.0.0.127
.
首先想到的是字节顺序,但是我看了MSDN文档(1 and 2),并没有提到字节顺序;这些函数会在没有明确说明的情况下任意决定使用其中一种符号,这对我来说似乎很奇怪。
这是怎么回事?
字节顺序是原因。
这些函数的重点不是生成 "readable" 整数,而是设置一个 32 位数量,准备好通过网络发送出去。 IPv4 需要 big-endian 排序,所以我敢打赌,如果你这样做 printf("%02X\n", ((char *)&IP)[0]));
,你会得到 C0
.
大于一个字节的数量(短整数、整数等)必须按照 Internet 标准要求的网络字节顺序离开线路,默认情况下是大端。
所以这些函数,如 inet_pton
、inet_ntoa
、htons
、htonl
和其他类似函数负责根据字节顺序交换这些数量的字节主持人。另一方面,接收方应使用相应的函数将网络字节顺序转换为正确的字节顺序。