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);
}