int inet_aton(const char *cp, struct in_addr *inp);
参数说明:
cp : IPv4点分十进制字符串,例如“192.168.1.2”、“10.28.1.1”等;
inp: 点分十进制转换成二进制后的结构体(网络字节序)
返回值:成功返回非0;失败返回0
注意:
这个函数已经将inp转换为网络字节序;已经将inp转换为网络字节序;已经将inp转换为网络字节序;
int inet_aton_demo()
{
char *string="192.168.1.2";
struct in_addr ip={0};
unsigned char *c=NULL;
int integer=0xc0a80102;/*用来对比测试*/
if(!inet_aton(string, &ip)){
printf("%s:%d error\n", __func__, __LINE__);
return -1;
}
printf("%8.8x ---- %u\n", ip.s_addr, ip.s_addr);/**/
c=(char *)&ip.s_addr;
printf("%2.2x ---- %2.2x --- %2.2x --- %2.2x\n", *c, *(c+1), *(c+2), *(c+3));
printf("%8.8x ---- %u\n", integer, integer);/**/
c=(char *)&integer;
printf("%2.2x ---- %2.2x --- %2.2x --- %2.2x\n", *c, *(c+1), *(c+2), *(c+3));
}
编译运行,结果如下:
root@ubantu:/mnt/hgfs/em嵌入式学习记录/schedule调度器# ./demo.out
0201a8c0 ---- 33663168
c0 ---- a8 --- 01 --- 02 --->inet_aton()转换后的字节序
c0a80102 ---- 3232235778
02 ---- 01 --- a8 --- c0 --->正常的主机字节序
root@ubantu:/mnt/hgfs/em嵌入式学习记录/schedule调度器#
从上述结果可以看出:
inet_aton()
会将点分十进制的字符串转换为网络字节序的二进制数。此时如果要做网络用途使用的话,无需再次转换(即,无需再通过htonl做转换);但是如果想在本地上查看转换后的结果,则需要做一个转换(需要使用ntohl)。
char *inet_ntoa(struct in_addr in);
参数说明:
inp: 点分十进制转换成二进制后的结构体(网络字节序)
返回值 : IPv4点分十进制字符串指针,例如“192.168.1.2”、“10.28.1.1”等;
注意:
不可重入,不可重入,不可重入
因为转换后的字符串使用同一块静态内存区,再次调用会被覆盖。
int inet_ntoa_demo()
{
char *string=NULL;
struct in_addr ip;
unsigned char *c=NULL;
ip.s_addr = 0xc0a80102;
/*
* 1. char *inet_ntoa(struct in_addr in);
*/
if(!(string=inet_ntoa(ip))){
printf("%s:%d %s\n", __func__, __LINE__, strerror);
return -1;
}
printf("%s\n", string);
printf("%8.8x ---- %u\n", ip.s_addr, ip.s_addr);/**/
c=(char *)&ip.s_addr;
printf("%2.2x ---- %2.2x --- %2.2x --- %2.2x\n", *c, *(c+1), *(c+2), *(c+3));
ip.s_addr = htonl(0xc0a80102);/*转换为网络字节序*/
if(!(string=inet_ntoa(ip))){
printf("%s:%d %s\n", __func__, __LINE__, strerror);
return -1;
}
printf("%s\n", string);
printf("%8.8x ---- %u\n", ip.s_addr, ip.s_addr);/**/
c=(char *)&ip.s_addr;
printf("%2.2x ---- %2.2x --- %2.2x --- %2.2x\n", *c, *(c+1), *(c+2), *(c+3));
/*
root@ubantu:/mnt/hgfs/em嵌入式学习记录/schedule调度器# ./demo.out
0201a8c0 ---- 33663168
c0 ---- a8 --- 01 --- 02
root@ubantu:/mnt/hgfs/em嵌入式学习记录/schedule调度器#
*/
}
编译运行,结果如下:
root@ubantu:/mnt/hgfs/em嵌入式学习记录/schedule调度器# ./demo.out
2.1.168.192
c0a80102 ---- 3232235778 ---主机字节序
02 ---- 01 --- a8 --- c0
192.168.1.2
0201a8c0 ---- 33663168 ---网络字节序
c0 ---- a8 --- 01 --- 02
root@ubantu:/mnt/hgfs/em嵌入式学习记录/schedule调度器#
从上述结果可以看出:
inet_ntoa()
会将二进制数以网络字节序的方式解析为点分十进制字符串。因此我们再定义in_addr变量时,直接将其s_addr的值转换为网络字节序;但是如果想在本地上查看转换后的结果,则需要做一个转换(需要使用ntohl)。
小结: 使用in_addr.s_addr时,这个值里存储的应该一直为网络字节序。本地想查看该变量的值,应作一次ntohl转换;如果做网络收发等等,则无需做任何转换。