Linux网络编程 - 域名与IP信息解析

现实中需要实现IP地址与域名的转换,常见的解析方式为DNS方式。还可以使用/etc/hosts文件进入简单的解析,解析中采用的顺序由文件/etc/hosts.conf决定。如下所示


通过域名返回主机信息


struct_hostent


示例代码

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include <unistd.h>  
  3. #include <stdlib.h>  
  4. #include <string.h>  
  5. #include <errno.h>  
  6. #include <sys/socket.h>  
  7. #include <netinet/in.h>  
  8. #include <arpa/inet.h>  
  9. #include <netdb.h>  
  10.   
  11. extern int h_errno;  
  12.   
  13. int main(int argc, char **argv)  
  14. {  
  15.     char   *ptr, **pptr;  
  16.     char    str[INET_ADDRSTRLEN];  
  17.     struct hostent *hptr;  
  18.     while (--argc> 0)   
  19.     {  
  20.         ptr = *++argv;  
  21.         if ( (hptr = gethostbyname (ptr) ) == NULL)   
  22.         {  
  23.             printf("gethostbyname error for host: %s: %s",ptr, hstrerror (h_errno) );  
  24.             continue;  
  25.         }  
  26.         printf ("official hostname: %s\n", hptr->h_name);  
  27.         for (pptr=hptr->h_aliases; *pptr!= NULL; pptr++)  
  28.             printf ("\talias: %s\n", *pptr);  
  29.         switch (hptr->h_addrtype)   
  30.         {  
  31.             case AF_INET:  
  32.                 pptr = hptr->h_addr_list;  
  33.                 for ( ; *pptr != NULL; pptr++)  
  34.                     printf ("\taddress: %s\n",inet_ntop (hptr->h_addrtype, *pptr, str, sizeof (str)));  
  35.                 break;  
  36.               
  37.             default:  
  38.                 printf("unknown address type");  
  39.                 break;  
  40.         }  
  41.     }  
  42.     exit(0);  
  43. }  
运行结果

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. $ ./gethostbyname localhost  
  2. official hostname: localhost  
  3.     alias: localhost.localdomain  
  4.     alias: localhost4  
  5.     alias: localhost4.localdomain4  
  6.     alias: localhost.localdomain  
  7.     alias: localhost6  
  8.     alias: localhost6.localdomain6  
  9.     address: 127.0.0.1  
  10.     address: 127.0.0.1  

通过域名和IP返回主机信息 


参数1:addr 类型为&char,含义是指向一个数组的指针,该数组含有一个主机地址(如IP地址)信息。
参数2:len 类型为int,含义是一个整数,它给出地址长度(IP 地址长度是4);
参数3:type 类型为int,含义是一个整数,它给出地址类型(IP 地址类型为AF_INET)。
如果成功,gethostbyaddr返回一个hostent 结构的指针。如果发生错误,返回0。

示例代码(运行之后出现段错误)

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2.   
  3. #include <stdlib.h>  
  4.   
  5. #include <string.h>  
  6.   
  7. #include <sys/types.h>  
  8.   
  9. #include <sys/socket.h>  
  10.   
  11. #include <netdb.h>  
  12.   
  13. #include <netinet/in.h>  
  14.   
  15. main(int argc, const char **argv)  
  16.   
  17. {  
  18.   
  19.     u_int addr;  
  20.   
  21.     struct hostent *hp;  
  22.   
  23.     char **p;  
  24.   
  25.     if (argc != 2)  
  26.   
  27.     {  
  28.   
  29.         printf("usage: %s IP-address\n",argv[0]);  
  30.   
  31.         exit(EXIT_FAILURE);  
  32.   
  33.     }  
  34.   
  35.     if ((int) (addr = inet_addr (argv[1])) == -1)   
  36.   
  37.     {  
  38.   
  39.         printf("IP-address must be of the form a.b.c.d\n");  
  40.   
  41.         exit (EXIT_FAILURE);  
  42.   
  43.     }  
  44.   
  45.     hp=gethostbyaddr((char *) &addr, sizeof (addr), AF_INET);  
  46.   
  47.     if (hp == NULL)   
  48.   
  49.     {  
  50.   
  51.         printf("host information for %s no found \n", argv[1]);  
  52.   
  53.         exit (EXIT_FAILURE);  
  54.   
  55.     }  
  56.   
  57.     for (p = hp->h_addr_list; *p!=0;p++)  
  58.   
  59.     {  
  60.   
  61.         struct in_addr in;  
  62.   
  63.         char **q;  
  64.   
  65.   
  66.   
  67.         memcpy(&in.s_addr, *p, sizeof(in.s_addr));  
  68.   
  69.   
  70.   
  71.         printf("%s\t%s",inet_ntoa(in), hp->h_name);//在此句出现段错误,下面无法输出  
  72.   
  73. printf("---  test  ---\n");  
  74.   
  75.         for (q=hp->h_aliases;*q != 0; q++)  
  76.   
  77.             printf("%s", *q);  
  78.   
  79.         printf("\n");  
  80.   
  81.     }  
  82.   
  83.     exit (EXIT_SUCCESS);  
  84.   
  85. }  

getaddrinfo获取主机信息


此函数第1个参数node为节点名:可以是主机名,也可以是二进制地址信息,如果是IPV4则为点分10进制,或是IPV6的16进制。
此函数第2个参数servname:包含十进制数的端口号或服务名,例如(ftp,http)。
这两个参数并不是总需要,如果此函数只用于域名解析,第2个参数可以不需要,如果要直接绑定到某个地址,例如访问对方的FTP服务器,则需要指定该端口号。
此函数第3个参数hints:一个空指针或指向一个addrinfo结构的指针,由调用者填写关于它所想返回的信息类型。
此函数第4个参数res:此参数用来存放返回addrinfo结构链表的指针地址信息。

示例代码(运行之后出现段错误)

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2.   
  3. #include <string.h>  
  4.   
  5. #include <netdb.h>  
  6.   
  7. #include <netinet/in.h>  
  8.   
  9. #include <sys/socket.h>  
  10.   
  11. #include <sys/types.h>  
  12.   
  13. int main(int argc,char *argv[])  
  14.   
  15. {  
  16.   
  17.     int rc;  
  18.   
  19.     char ipbuf[16];  
  20.   
  21.       
  22.   
  23.     struct addrinfo hints,*addr;  
  24.   
  25.       
  26.   
  27.     memset(&hints,0,sizeof(struct addrinfo));  
  28.   
  29.     hints.ai_family=AF_INET;  
  30.   
  31.     hints.ai_flags=AI_CANONNAME | AI_ADDRCONFIG;  
  32.   
  33.   
  34.   
  35.     if((rc=getaddrinfo(argv[1],argv[2],&hints,&addr))==0)  
  36.   
  37.     {  
  38.   
  39.         do{  
  40.   
  41.             printf("ip: %s\t",inet_ntop(AF_INET, &(((struct sockaddr_in*)addr->ai_addr)->sin_addr), ipbuf, sizeof(ipbuf)));//在此句出现段错误,下面无法输出  
  42.   
  43.             printf("host:%s\t",addr->ai_canonname);  
  44.   
  45.             printf("length:%d\t",addr->ai_addrlen);  
  46.   
  47.             printf("port:%d\n",ntohs(((struct sockaddr_in *)addr->ai_addr)->sin_port));  
  48.   
  49.         }while((addr=addr->ai_next)!=NULL);   
  50.   
  51.         return 0;  
  52.   
  53.     }  
  54.   
  55.     printf("%d\n",rc);  
  56.   
  57.     return 0;  
  58.   
  59. }  

原文链接

http://blog.csdn.net/geng823/article/details/42001475

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值