gethostbyname函数 : 是将主机名转换成对应的IPv4地址;
包含头文件 #include <netdb.h>
函数原型:
struct hostent *gethostbyname(const char *hostname) //返回: 成功返回一个非空指针,否则返回NULL并设置errno的值
返回:
>>> 调用成功,返回一个指向hostent结构的指针,该结构含有所查找主机的所有IPv4地址;
>>> 调用失败,返回空指针NULL,并重置h_errno全局整数变量的值(一般会调用hstrerror函数返回相应错误的说明)
局限: 只能返回IPv4地址;
hstrerror函数的简单介绍:
它以某个h_errno的值作为唯一的参数,返回的是一个const char * 的指针,指向对应错误的说明;
参数h_errno的简单介绍:
当发生错误时,系统将全局整数变量h_errno设置为在头文件<netdb.h>中定义的常值:
HOST_NOT_FOUND;
TRY_AGAIN;
NO_RECOVERY;
NO_DATA; (== NO_ADDRESS)
hostent结构的简单介绍:
struct *hostent { char *h_name; //正式主机名; char **h_aliases; //别名; int h_addrtype; //地址类型; int h_length; //地址长度,一般为4; char **h_addr_list; //地址序列; };
注意:
如上图, 因为gethostbyname返回的只能是IPv4的地址,不能返回IPv6的地址,所以结构中的地址类型改成AF_INET,长度改成4,才是正确的;
而且,就算该主机中含有IPv6地址,通过gethostbyname函数调用返回的野仅仅是IPv4地址!!!
如下是gethostbyname函数的一个简单的实现:
给每个命令行参数调用gethostbyname函数;
输出正式主机名(或规范名),后跟别名列表;
pptr指向一个指针数组,其中每个指针指向一个地址,对于每个地址,我们调用inet_ntop函数并输出返回的字符串;
#include <unp.h> #include <netdb.h> 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) { err_msg("gethostbyname error for host : %s : %s", ptr, hstrerror(h_errno)); continue; } printf("official hostname : %s\n", hptr->h_name); for(pptr=hptr->h_aliases; *pptr!=NULL; pptr++) { printf("\taliases : %s\n", *pptr); } switch(hptr->h_addrtype) { case AF_INET: pptr = hptr->h_addr_list; for( ; *pptr!=NULL; pptr++) { printf("\taddress : %s", inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str))); } break; default: err_ret("unknown address type"); break; } } exit(0); }