IP地址有两种格式:一种被人理解的点分十进制字符串格式,另一种是被计算机理解的二进制地址格式。当需要将ip地址打印出来的时候人们希望打印点分十进制格式,而在进行传送的格式的时候又必须转换成二进制地址格式。
常用的地址转换函数包括inet_addr()、inet_nota()、inet_aton()、inet_network(),通过测试这些函数或多或少的存在着一些缺陷,比如255.255.255.255,用inet_addr()、inet_ntoa()两个函数的时候如果加上判定条件出错返回-1,执行错误语句,但是如果正常打印依然会打印出一个网络字节序的二进制数。inet_aton()函数随意输入“adg”经过inet_addr()函数转换后,依然会打印出一个ip地址出来。不解。。。
个人推荐使用较新的两个转换函数:
-
#include<arpa/inet.h>
-
#include<netinet/in.h>
-
-
const char *inet_ntop(int domain, const void *restrict addr, char *restrict str, socklen_t size);
-
返回值:成功返回指向地址字符串指针,若出错返回NULL;
-
-
int inet_pton(int domain, const char * restrict str, void *restrict addr);
-
返回值:若成功返回1,无效返回0,出错返回-1;
inet_ntop函数说明:将网络字节序的二进制地址转换成为文本字符串格式。
domian:只有两种取值,AF_INET和AF_INET6;
addr:为待转的网络字节序的二进制地址;
str:为存放转换后的点分十进制地址缓冲;
size:指定用于保存文本字符串的缓冲区str的大小。INET_ADDRSTRLEN和INET6_ADDRSTRLEN定义了足够的存储IPv4和IPv6地址缓冲的大小。
inet_pton函数说明:将文本字符串格式转换成为网络字节序的二进制地址。
domian:只有两种取值,AF_INET和AF_INET6;
str:为待转的文本字符串格式的地址;
addr:为存放网络字序的二进制地址格式;
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
#include <unistd.h>
-
#include <sys/socket.h>
-
#include <netinet/in.h>
-
#include <arpa/inet.h>
-
-
int main (void)
-
{
-
char *src;
-
const char *ch;
-
int rc;
-
struct in_addr inet_pton_r;
-
memset(&inet_pton_r,0,sizeof(inet_pton_r));
-
src = (char *)malloc(20*sizeof(char));
-
// 输入IP地址
-
printf("Please input IP address: \n");
-
scanf("%s", src);
-
//点分十进制地址格式--->网络字序的二进制格式
-
rc = inet_pton(AF_INET,src,(void *)&inet_pton_r);
-
if (rc > 0)
-
{
-
printf("inet_pton_r:%lu\n",inet_pton_r.s_addr);
-
}
-
else
-
{
-
perror("inet_pton");
-
}
-
//网络字序的二进制格式--->点分十进制地址格式
-
ch = inet_ntop(AF_INET,(void *)&inet_pton_r.s_addr,src,INET_ADDRSTRLEN);
-
if (ch == NULL)
-
{
-
perror("inet_ntop");
-
}
-
else
-
{
-
printf("inet_ntop:%s\n",src);
-
}
-
-
free(src);
-
return 0;
-
}
结果:
当输入非法的时候inet_ntop转换出来的地址是0.0.0.0;
关于ip地址0.0.0.0:
严格说来,0.0.0.0已经不是一个真正意义上的IP地址了。它表示的是这样一个集合:所有不清楚的主机和目的网络。这里的“不清楚”是指在本机的路由表里没有特定条目指明如何到达。对本机来说,它就是一个“收容所”,所有不认识的“三无”人员,一律送进去。如果你在网络设置中设置了缺省网关,那么Windows系统会自动产生一个目的地址为0.0.0.0的缺省路由。
通常情况下,网络中所说的0.0.0.0的IP地址表示整个网络,即网络中的所有主机。
但在一些老的软件中,他们可能将0.0.0.0做为广播地址使用,即他们发送广播数据包时,目标地址址不是255.255.255.255,而是0.0.0.0。所以,当协议分析软件抓到IP是0.0.0.0的主机时,表示网络存在将0.0.0.0做为广播地址进行通讯的情况,而不是代表整个网络。
注意:0.0.0.0做为广播地址已经基本上被废弃,当前的网络程序或设备一般都不会将0.0.0.0做为广播地址。
在网络中出现0.0.0.0时,我们需要检查该数据包的源主机,检查其是否是人为手动使用某些老的软件产生的这种数据包,或者是由于某些非法攻击产生的该数据包。
仅仅使用inet_aton()还是可以的,但是inet_ntoa始终觉得有些不妥,下面给出一个inet_aton()的例子。
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
#include <unistd.h>
-
#include <sys/socket.h>
-
#include <netinet/in.h>
-
#include <arpa/inet.h>
-
-
int main (void)
-
{
-
char *src;
-
int rc;
-
in_addr_t inet_addr_r,inet_network_r;
-
struct sockaddr_in inet_aton_r;
-
struct in_addr inet_ntoa_r;
-
memset(&inet_ntoa_r,0,sizeof(inet_ntoa_r));
-
src = (char *)malloc(20*sizeof(char));
-
// 输入IP地址
-
printf("Please input IP address: \n");
-
scanf("%s", src);
-
-
rc = inet_aton(src,&inet_aton_r.sin_addr);
-
if (rc == 0)
-
{
-
printf("input illegal!\n");
-
}
-
else
-
{
-
printf("result of inet_aton:%lu\n",inet_aton_r.sin_addr);
-
}
-
free(src);
-
return 0;
-
}
阅读(6110) | 评论(0) | 转发(0) |