gethostbyname函数通常用于根据域名获取ip地址,函数原型如下所示
#include <netdb.h>
struct hostent *gethostbyname(const char *name);
函数返回hostent结构指针,如果失败则返回NULL指针。
hostent结构定义如下所示
struct hostent {
char *h_name; // 主机规范名
char **h_aliases; // 主机别名,可能有多个别名,以空指针结束
int h_addrtype; // 主机IP地址类型
int h_length; // 主机IP地址长度
char **h_addr_list; // 主机IP地址,需要使用inet_ntop函数转换
}
#define h_addr h_addr_list[0]
如果gethostbyname函数失败,会设置全局的h_errno标识错误类型,并可通过const char *hstrerror(int err);函数输出具体错误描述。
以下为一个使用gethostbyname的例子
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <time.h>
#include <stdio.h>
int main(int argc, char **argv)
{
char *ptr, **pptr;
struct hostent *hptr;
char str[128];
if (argc < 2) {
printf("usage: ./a.out www.baidu.com\n");
return -1;
}
ptr = argv[1];
time_t begin = time(NULL);
if ((hptr = gethostbyname(ptr)) == NULL) {
printf(" gethostbyname error [%s] for host:%s\n", hstrerror(h_errno), ptr);
time_t end = time(NULL);
printf("gethostbyname error, used [%ld] times\n", end - begin);
return 0;
}
printf("official hostname:%s\n", hptr->h_name);
for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
printf(" alias:%s\n", *pptr);
switch (hptr->h_addrtype) {
case AF_INET:
case AF_INET6:
pptr = hptr->h_addr_list;
for(; *pptr != NULL; pptr++)
printf(" address:%s\n", inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));
break;
default:
printf("unknown address type\n");
break;
}
return 0;
}
简单编译运行,获取新浪网ip,执行结果如下所示:
gcc gethostbyname.c -o get
./get www.sina.com
official hostname:ww1.sinaimg.cn.w.alikunlun.com
alias:www.sina.com
alias:spool.grid.sinaedge.com
address:125.94.49.222
address:14.29.40.201
address:14.29.40.203
address:125.94.49.220
address:125.94.49.224
address:14.29.40.205
address:125.94.49.223
address:14.29.40.200
address:119.147.70.217
address:14.29.40.202
address:119.147.70.219
address:119.147.70.220
address:119.147.70.216
address:14.29.40.204
address:119.147.70.218
address:125.94.49.221
异常情况
通常都是在网络联通情况下调用gethostbyname函数,可能并不会发现它其实会阻塞。
在网络信号不好或连接的热点不能上网的情况下,gethostbyname会阻塞10秒钟。
如笔者在虚拟机上执行上述程序,但禁用主机的网卡,执行后结果显示如下:
gethostbyname error [Unknown host] for host:www.sina.com
gethostbyname error, used [10] times
要解决这个问题,我们可以引入超时信号或在调用gethostbyname之前主动查询DNS信息。在访问DNS时我们可以控制等待时间,只有DNS访问成功的情况下才再调用gethostbyname。也就是将阻塞时间挪到DNS访问,并可自控。
详细参考:c++实现DNS域名解析
本文介绍了C++中gethostbyname函数的用途,用于根据域名获取IP地址。当网络状况不佳时,该函数可能会阻塞长达10秒。通过示例代码展示了gethostbyname的使用,并提出了在网络连接不稳定时可能导致的问题。为解决阻塞问题,建议在调用前先进行DNS查询并设置超时控制。
5072

被折叠的 条评论
为什么被折叠?



