最近解决了一个bug,是由于之前同事对于inet_ntop和inet_pton函数的理解存在问题,因此结合网络编程卷一书中的内容,将此部分内容总结记录。
函数原形:

 #include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);
const char *inet_ntop(int af, const void *src,char *dst, socklen_t size);

首先指出的是这两个函数是随IPv6出现的新函数,对于IPv4和IPv6都适用。函数名中的p和n分别代表表达(presentation)和数值(numeric)。这两个函数的family既可以是AF_INET,也可以是AF_INET6.
首先我们需要搞清楚的是什么是表达类型,什么是数值类型。

#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
int main()
{
    struct in_addr addr;
    if(inet_pton(AF_INET, "127.0.0.1", &addr.s_addr) == 1)
        printf("Numeric IP: %x\n", addr.s_addr);
    char str[16];
    if(inet_ntop(AF_INET, &addr.s_addr, str, sizeof(str)))
        printf("Presentation IP: %s\n", str);
    return 0;
}

函数执行结果:

Numeric IP: 100007f
Presentation IP: 127.0.0.1


我们在man手册里看到struct in_addr存储的ip地址是网路字节序即大端方式,Numeric IP输出的为十六进制0x 01 00 00 00 00 7f.
大端方式小端方式可以参考如下内容:
例如假设变量x类型为int,位于地址0x100处,它的十六进制为0x01234567,地址范围为0x100~0x103字节,其内部排列顺序依赖于机器的类型。大端法从首位开始将是:0x100: 01, 0x101: 23,..。而小端法将是:0x100: 67, 0x101: 45,..。
大端表示法高字节在低地址处,我们改写程序验证in_addr中存的地址为网络字节序即大端方式:

#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
int main()
{
    struct in_addr addr;
    if(inet_pton(AF_INET, "127.0.0.1", &addr.s_addr) == 1)
        printf("Numeric IP: %x\n", addr.s_addr);
    
    printf("Numeric IP: %x\n", addr.s_addr&255);
    char str[16];
    if(inet_ntop(AF_INET, &addr.s_addr, str, sizeof(str)))
        printf("Presentation IP: %s\n", str);
    return 0;
}

执行结果:
Numeric IP: 100007f
Numeric IP: 7f
Presentation IP: 127.0.0.1
因此低地址存放的高位7f因此证明struct in_addr中为网络字节序即大端方式。