域名,简单来理解就是我们平常说的网址。比如登录某度买假药时,会在IE浏览器的地址栏输入www.baidu.com,这里我们输入的就是百度的域名。而实际上我们在互联网中要找到某个网站,是需要这个网站的IP地址的,因为在网络中IP地址就是一台主机的联系地址,而通过域名寻找主机时,就需要先将域名转换成IP地址,这就是我们通常说的DNS服务器的作用。
网络编程中,我们通过gethostbyname函数可以通过域名获取主机信息。所谓主机信息就是网络那头web服务器的信息,其中就包含该服务器的IP地址。gethostbyname的函数原型如下:
#include
struct hostent *gethostbyname(const char *name);
它接收的唯一参数就是我们在浏览器中输入的域名,在前面的例子中也就是某度的url:www.baidu.com。而他的返回值是一个hostent类型的指针,该结构体的定义如下:
struct hostent
{
char* h_name;
char** h_aliases;
int h_addrtype;
int h_length;
char** h_addr_list;
}
h_addr_list,保存的是IP地址的列表。因为同一个域名可能分配给了多个IP地址,以缓解用户访问的压力,所以这里包含了多个IP地址。但是,值得注意的是,这里面保存的并不是字符串类型的IP地址,而是in_addr结构体变量的地址,也就是说h_addr_list实际上保存的是指针(为了兼容后续的IPv6d地址信息的指针,这里面的指针类型是char* ,而非in_addr*),指向了了in_addr结构体对象,而in_addr包含了IP地址信息。如果我们想要把in_addr结构体变成我们熟悉的点分十进制格式的IP地址,可以借助inet_ntoa()函数,用法请参照后面的例子。
下面是in_addr结构体的定义:
strcut in_addr
{
in_addr_t s_addr; //32 位的IPv4地址
}
#include
#include
#include
void error_handling(char *message);
int main(int argc,char* argv[])
{
int i;
struct hostent* host;
if(argc!=2)
{
printf("Usage %s ",argv[0]);
exit(1);
}
host=gethostbyname(argv[1]);
if(!host)
{
error_handling("gethostbyname error");
}
printf("official name is %s\n",host->h_name);
for(i=0;host->h_aliases[i];i++)
{
printf("Aliases %d: %s\n",i+1,host->h_aliases[i]);
}
printf("Address type: %s\n",
host->h_addrtype==AF_INET?"AF_INET":"AF_INET6");
for(i=0;host->h_addr_list[i];i++)
{
printf("IP addr %d: %s \n",i+1,
inet_ntoa(*(struct in_addr*)host->h_addr_list[i]));
}
return 0;
}
void error_handling(char* message)
{
fputs(message,stderr);
fputc('\n',stderr);
exit(0);
}
结果如下,发现该度设置了两个IP地址,分别是14.215.177.38和14.215.177.37.
我们在浏览器里可以直接输入ip地址来访问该度:
想利用IP地址获取域名,使用gethostbyaddr函数:
#include
##include /* for AF_INET */
struct hostent *gethostbyaddr(const void *addr,
socklen_t len, int type);
#include
#include
#include
#include
#include
#include
void error_handling(char *message);
int main(int argc,char* argv[])
{
int i;
struct hostent* host;
struct sockaddr_in addr;
if(argc!=2)
{
printf("Usage %s ",argv[0]);
exit(1);
}
memset(&addr,0,sizeof(addr));
addr.sin_addr.s_addr=inet_addr(argv[1]);
host=gethostbyaddr((char*)&addr.sin_addr.s_addr,4,AF_INET);
if(!host)
{
error_handling("gethostbyaddr error");
}
printf("official name is %s\n",host->h_name);
for(i=0;host->h_aliases[i];i++)
{
printf("Aliases %d: %s\n",i+1,host->h_aliases[i]);
}
printf("Address type: %s\n",
host->h_addrtype==AF_INET?"AF_INET":"AF_INET6");
for(i=0;host->h_addr_list[i];i++)
{
printf("IP addr %d: %s \n",i+1,
inet_ntoa(*(struct in_addr*)host->h_addr_list[i]));
}
return 0;
}
void error_handling(char* message)
{
fputs(message,stderr);
fputc('\n',stderr);
exit(0);
}
结果:
Github位置:
https://github.com/HymanLiuTS/NetDevelopment
克隆本项目:
git clone [email protected]:HymanLiuTS/NetDevelopment.git
获取本文源代码:
git checkout NL08