學習筆記之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\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  完美的成功了,正當高興的時候。

  ./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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM