zoukankan      html  css  js  c++  java
  • 学习笔记之gethostbyaddr函数

      刚才学了gethostbyname函数,这个gethostbyaddr函数的作用是通过一个IPv4的地址来获取主机信息,并放在hostent结构体中。

    #include <netdb.h>
    struct hostent * gethostbyaddr(const char * addr, socklen_t len, int family);//返回:若成功则为非空指针,若出错则为NULL且设置h_errno 
    //上面的const char * 是UNP中的写法,而我在linux 2.6中看到的是 const  void *

      本函数返回一个指向hostent结构指针。addr参数实际上不是char * 类型,而是一个指向存放IPv4地址的某个in_addr结构的指针;len参数是这个结构的大小,对于IPv4地址为4;family参数为AF_INET。

      先不多说,先给出代码 (CentOS 6.4)

     1 #include <stdio.h>
     2 #include <netdb.h>
     3 #include <arpa/inet.h>
     4 #include <sys/socket.h>
     5 
     6 int main(int argc,char **argv)
     7 {
     8     char *ptr,**pptr;
     9     char str[INET_ADDRSTRLEN];
    10     struct hostent *hptr;
    11     struct in_addr * addr;
    12     struct sockaddr_in saddr;
    13 
    14     //取参数
    15     while(--argc>0)
    16     {
    17       ptr=*++argv; //此时的ptr是ip地址
    18       if(!inet_aton(ptr,&saddr.sin_addr)) //调用inet_aton(),将ptr点分十进制转in_addr
    19       {
    20           printf("Inet_aton error
    ");
    21           return 1;
    22       }
    23 
    24       if((hptr=gethostbyaddr((void *)&saddr.sin_addr,4,AF_INET))==NULL) //把主机信息保存在hostent中
    25       {
    26           printf("gethostbyaddr error for addr:%s
    ",ptr);
    27           printf("h_errno %d
    ",h_errno);
    28           return 1;
    29       }
    30       printf("official hostname: %s
    ",hptr->h_name);//正式主机名
    31 
    32       for(pptr=hptr->h_aliases;*pptr!=NULL;pptr++)//遍历所有的主机别名
    33           printf("	alias: %s
    ",*pptr);
    34 
    35       switch(hptr->h_addrtype)//判断socket类型
    36       {
    37           case AF_INET:  //IP类为AF_INET
    38           case AF_INET6:  //IP类为AF_INET6
    39             pptr=hptr->h_addr_list; //IP地址数组
    40             for(;*pptr!=NULL;pptr++)
    41                 printf("	address: %s
    ",
    42                     inet_ntop(hptr->h_addrtype,*pptr,str,sizeof(str)));//inet_ntop转换为点分十进制
    43             break;
    44           default:
    45             printf("unknown address type
    ");
    46             break;
    47       }
    48     }
    49     return 0;
    50 }

      从代码中可以看到,gethostbyaddr的第一个参数是sockaddr_in而不是in_addr类型。我做实验的时候用in_addr作为参数,总是不行,也不知道为什么。就将就用了sockaddr_in了。

      然后我 编译后运行  

      ./gethostbyaddr 127.0.0.1  完美的成功了,正当高兴的时候。

      ./gethostbyaddr 115.239.211.110 (百度域名的ip) 

      竟然出错了,是gethostbyaddr error for addr:115.239.211.110 而h_errno是为2的。

      就找到了这一篇文章:https://community.oracle.com/thread/1926589?start=0&tstart=0 

      我改了 /etc/resolv.conf 增加了一个 nameserver 8.8.8.8

      再次运行,又错了,这次的错误代码是h_errno=1。

      于是就又找到了这一篇文章:http://kb.zmanda.com/article.php?id=139

      什么,竟然要手动在/etc/hosts下增加?算了,就先试一下。写上 115.239.211.110 www.baidu.com ,运行,成功了。

      ---------------------------------------------------------------------------

      正在想为什么会这样的时候,看到UNP里面的一句话: 按照DNS的说法,gethostbyaddr在in_addr.arpa域中向一个名字服务器查询PTR记录。

      可能是我的电脑不是服务器吧,没有域名解析服务吧。所以不行。而本地的/etc/hosts差不多就是有这个功能。我就在想为什么gethostbyname会向/etc/hosts文件中查看信息,然后没有对应的话,就会返回上一级的DNS进行解析。而反向解析为什么不会自动解析呢?(Ps我想会不会是反向解析比较少用到,而且正向解析域名有层次关系,而IP没有层次关系,不方便处理吧。)我通过nslookup 115.239.211.110 进行查询时提示这个错误:

    ** server can't find 110.211.239.115.in-addr.arpa.: NXDOMAIN

      好了,没错了,要使用这个函数,本地要有反向解析的服务。

      本文地址:http://www.cnblogs.com/wunaozai/p/3753731.html

  • 相关阅读:
    TypeScript
    monorepo
    Sass和Less
    浏览器的多进程
    React router的Route应用
    CSS3 之 Media(媒体查询器)
    迷失了自己~
    实现跨域的项目实践
    Python开发入门14天集训营-第二章
    Python开发入门14天集训营-第一章
  • 原文地址:https://www.cnblogs.com/wunaozai/p/3753731.html
Copyright © 2011-2022 走看看