概述gethostbynamegethostbyname流程
/etc/nsswitch.conf先files后dns验证先dns后files验证 gethostname实例gethostbyaddrgethostbyaddr实例
概述我们通常使用主机名而不是数值地址来访问主机,主机名可以是简单的名字,也可以是全限定域名。unix提供了gethostbyname实现主机名到地址之间的转换,gethostbyaddr实现地址到主机名之间的转换。
gethostbyname实现主机名到地址之间的转换,仅支持IPv4,函数原型如下:
#includestruct hostent *gethostbyname(const char *hostname); - hostname: 字符串形式的主机名 - return: hostent结构的主机信息
gethostbyname和其他socket函数不同,出错时它不会修改errno,而是修改netdb.h中定义的h_errno,t通过调用hstrerror(h_errno)获取错误信息的字符串表示,错误信息如下:
HOST_NOT_FOUND: 记录未找到TRY_AGAIN: 重试NO_RECOVERY: DNS服务不可达NO_data: 记录能找到,但是没有A记录,如只有AAAA记录的域名 gethostbyname流程 /etc/nsswitch.conf
如果在本机/etc/hosts中加了www.baidu.com,在调用gethostbyname访问www.baidu的时候,优先从本机hosts中读取,还是向DNS请求域名呢?
# cat /etc/hosts 3.3.3.3 www.baidu.com testhostalias5 testhostalias6
结论是,如果本机安装了nscd,那么优先从nscd缓存中获取a/aaaa记录,如果没有安装,那么根据/etc/nsswitch.conf的配置,确定优先从哪里获取记录。
/etc/nsswitch.conf中关于hosts的配置如下:
#hosts: files dns myhostname hosts: dns files myhostname
files: 本机文件,如hosts对应/etc/hosts,账户密码对应/etc/passwddns: 根据配置/etc/resolv.conf,从DNS服务器上请求 先files后dns验证
# ./a.out www.baidu.com
official hostname: www.baidu.com
alias: testhostalias5
alias: testhostalias6
address: 3.3.3.3
直接从hosts获取结果,hosts中如果没有,立即从DNS服务器上请求。
先dns后files验证# ./a.out www.baidu.com
official hostname: www.a.shifen.com
alias: www.baidu.com
address: 36.152.44.96
address: 36.152.44.95
直接从DNS服务器请求结果,如果DNS服务器没有结果,超时后从hosts文件获取结果。
gethostname实例附上unp上的实例:
#includegethostbyaddr#include #include #include #include #include int main(int argc, char **argv) { char *ptr, **pptr; char str[INET_ADDRSTRLEN]; struct hostent *hptr; while (--argc > 0) { ptr = *++argv; if ((hptr = gethostbyname(ptr)) == NULL) { printf("gethostbyname error for host: %s: %sn", ptr, hstrerror(h_errno)); continue; } printf("official hostname: %sn", hptr->h_name); for (pptr = hptr->h_aliases; *pptr != NULL; pptr++) { printf("talias: %sn", *pptr); } switch (hptr->h_addrtype) { case AF_INET: pptr = hptr->h_addr_list; for ( ; *pptr != NULL; pptr++) { inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)); printf("taddress: %sn", str); } break; default: printf("unknow address type"); break; } } return 0; }
gethostbyaddr实现根据地址获取主机名,也就是DNS中的ptr记录。函数原型如下:
#includegethostbyaddr实例struct hostent *gethostbyaddr (const void *addr, socklen_t len, int type); - addr: struct in_addr类型指针 - len: IPv4长度,4 - type: 协议族,A - return: struct hostent指针
#include#include #include #include #include #include int main(int argc, char **argv) { char *ptr, **pptr; char s_addr[256]; struct in_addr addr; socklen_t len = 4; struct hostent *hstent; while(--argc > 0){ argv++; strncpy(s_addr, *argv, sizeof(s_addr)); inet_aton(s_addr, &addr); if ((hstent = gethostbyaddr(&addr, len, AF_INET)) == NULL){ printf("gethostaddr %s failed %sn", s_addr, hstrerror(h_errno)); } printf("addr : %s --> hostname : %sn", s_addr, hstent->h_name); } return 0; }



