Chinaunix首页 | 论坛 | 博客
  • 博客访问: 373921
  • 博文数量: 48
  • 博客积分: 1032
  • 博客等级: 上士
  • 技术积分: 1256
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-19 13:24
文章分类

全部博文(48)

文章存档

2014年(3)

2013年(23)

2012年(22)

分类: LINUX

2012-10-30 09:57:13

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地址出来。不解。。。

个人推荐使用较新的两个转换函数:

点击(此处)折叠或打开

  1. #include<arpa/inet.h>
  2. #include<netinet/in.h>

  3. const char *inet_ntop(int domain, const void *restrict addr, char *restrict str, socklen_t size);
  4. 返回值:成功返回指向地址字符串指针,若出错返回NULL;

  5. int inet_pton(int domain, const char * restrict str, void *restrict addr);
  6. 返回值:若成功返回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:为存放网络字序的二进制地址格式;

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/socket.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>

  8. int main (void)
  9. {
  10.     char *src;
  11.     const char *ch;
  12.     int rc;
  13.     struct in_addr inet_pton_r;
  14.     memset(&inet_pton_r,0,sizeof(inet_pton_r));
  15.     src = (char *)malloc(20*sizeof(char));    
  16.     // 输入IP地址
  17.     printf("Please input IP address: \n");
  18.     scanf("%s", src);
  19.     //点分十进制地址格式--->网络字序的二进制格式
  20.     rc = inet_pton(AF_INET,src,(void *)&inet_pton_r);
  21.     if (rc > 0)
  22.         {
  23.             printf("inet_pton_r:%lu\n",inet_pton_r.s_addr);
  24.         }
  25.     else
  26.         {
  27.             perror("inet_pton");
  28.         }
  29.      //网络字序的二进制格式--->点分十进制地址格式
  30.      ch = inet_ntop(AF_INET,(void *)&inet_pton_r.s_addr,src,INET_ADDRSTRLEN);            
  31.      if (ch == NULL)
  32.         {
  33.              perror("inet_ntop");    
  34.          }
  35.      else
  36.          {
  37.               printf("inet_ntop:%s\n",src);    
  38.           }
  39.             
  40.      free(src);
  41. return 0;
  42. }
结果:
当输入非法的时候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()的例子。

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/socket.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>

  8. int main (void)
  9. {
  10.     char *src;
  11.     int rc;
  12.     in_addr_t inet_addr_r,inet_network_r;
  13.     struct sockaddr_in inet_aton_r;
  14.     struct in_addr inet_ntoa_r;
  15.     memset(&inet_ntoa_r,0,sizeof(inet_ntoa_r));
  16.     src = (char *)malloc(20*sizeof(char));    
  17.     // 输入IP地址
  18.     printf("Please input IP address: \n");
  19.     scanf("%s", src);
  20.     
  21.     rc = inet_aton(src,&inet_aton_r.sin_addr);
  22.     if (rc == 0)
  23.       {
  24.         printf("input illegal!\n");
  25.       }
  26.     else
  27.       {
  28.          printf("result of inet_aton:%lu\n",inet_aton_r.sin_addr);                
  29.        }
  30.     free(src);
  31. return 0;
  32. }




阅读(5279) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~