为什么inet_ntoa和inet_ntop“反转”字节?
这是一个相当基本的问题,令我惊讶的是,我今天遇到了一个问题。
它看起来像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
。
首先想到的是endianness,但我已经阅读了MSDN文档( 1和2 )并且没有提到字节顺序; 这对我来说似乎很奇怪,这些函数会随意决定使用其中一种符号而没有明确说明。
到底是怎么回事?
Endianness 是原因。
这些函数的重点不是产生一个“可读”的整数,而是设置一个准备好在线上运出的32位数量。 IPv4需要big-endian排序,所以如果你做了printf("%02X\n", ((char *)&IP)[0]));
,我会打赌printf("%02X\n", ((char *)&IP)[0]));
,你得到C0
。
大小超过一个字节的数量(短路,整数等)必须按照Internet标准要求以网络字节顺序保留线路,默认情况下是Big-endian。
因此,这些函数,如inet_pton
, inet_ntoa
, htons
, htonl
和其他类似函数,负责根据主机的字节顺序交换这些数量的字节。 另一方面,接收器应使用相应的函数将网络字节顺序转换为正确的字节顺序。