刚才学了gethostbyname函数,这个gethostbyaddr函数的做用是经过一个IPv4的地址来获取主机信息,并放在hostent结构体中。php
#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。html
先很少说,先给出代码 (CentOS 6.4)linux
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\n"); 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\n",ptr); 27 printf("h_errno %d\n",h_errno); 28 return 1; 29 } 30 printf("official hostname: %s\n",hptr->h_name);//正式主机名
31
32 for(pptr=hptr->h_aliases;*pptr!=NULL;pptr++)//遍历全部的主机别名
33 printf("\talias: %s\n",*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("\taddress: %s\n", 42 inet_ntop(hptr->h_addrtype,*pptr,str,sizeof(str)));//inet_ntop转换为点分十进制
43 break; 44 default: 45 printf("unknown address type\n"); 46 break; 47 } 48 } 49 return 0; 50 }
从代码中能够看到,gethostbyaddr的第一个参数是sockaddr_in而不是in_addr类型。我作实验的时候用in_addr做为参数,老是不行,也不知道为何。就将就用了sockaddr_in了。数组
而后我 编译后运行 服务器
./gethostbyaddr 127.0.0.1 完美的成功了,正当高兴的时候。oracle
./gethostbyaddr 115.239.211.110 (百度域名的ip) socket
居然出错了,是gethostbyaddr error for addr:115.239.211.110 而h_errno是为2的。函数
就找到了这一篇文章:https://community.oracle.com/thread/1926589?start=0&tstart=0 spa
我改了 /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
好了,没错了,要使用这个函数,本地要有反向解析的服务。