我们通常在网页上访问一个网址,例如访问百度时,我们通常是输入www.baidu.com,这种表示是代表百度的域名,实际上当我们在访问这个网址的时候,操作系统会自动向DNS服务器发送请求,来获取百度的ip,完成域名到ip的转换。
在计算机网络中,通常我们我们在访问一个网址时,输入的是该网址的域名,而不是ip,因为像百度这种网址的ip通常是公有ip,这种ip是会变的,我们当然不会去记它会变的ip,而通过访问域名的方法来访问百度就会更方便,因为域名是不会变的。
C中提供一个函数gethostbyname()来实现域名到ip的转换
头文件#include<netdb.h>
函数原型struct hostent *gethostbyname(const char *name);
函数调用失败返回NULL;
struct hostent
{
char *h_name;
char **h_aliases;
int h_addrtype;
int h_length;
char **h_addr_list;
#define h_addr h_addr_list[0];
};
hostent->h_name
表示的是主机的规范名。例如www.google.com的规范名其实是www.l.google.com。
hostent->h_aliases
表示的是主机的别名.www.google.com就是google他自己的别名。有的时候,有的主机可能有好几个别名,这些,其实都是为了易于用户记忆而为自己的网站多取的名字。
hostent->h_addrtype
表示的是主机ip地址的类型,到底是ipv4(AF_INET),还是pv6(AF_INET6)
hostent->h_length
表示的是主机ip地址的长度
hostent->h_addr_lisst
表示的是主机的ip地址,注意,这个是以网络字节序存储的。千万不要直接用printf带%s参数来打这个东西,会有问题的哇。所以到真正需要打印出这个IP的话,需要调用inet_ntop()。
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) :
这个函数,是将类型为af的网络地址结构src,转换成主机序的字符串形式,存放在长度为cnt的字符串中。返回指向dst的一个指针。如果函数调用错误,返回值是NULL。
接下来通过代码来验证
:编程环境Ubuntu14.04下vim
(使用命令行参数来执行)
#include<stdio.h>
#include<netdb.h>
#include<getopt.h>
#include<errno.h>
#include<sys/types.h>
#include<arpa/inet.h>
void usage(char *progname)
{
printf("Usage %s\n",progname);
printf("-h(--hostname) :sepcify hostname\n");
return ;
}
int main(int argc,char **argv)//使用命令行参数
{
const char *ptr=NULL;
char **pptr=NULL;
char buf[20]={0};
char ch=0;
char *name=NULL;
struct hostent *getname=NULL;
struct option opts[]={
{"hostname",required_argument,NULL,'h'},
{NULL,0,NULL,0}
};
while((ch=getopt_long(argc,argv,"h:",opts,NULL))!=-1)
{
switch(ch)
{
case 'h':
name=optarg;
break;
default:
usage(argv[0]);
break;
}
}
if(!name)
{
usage(argv[0]);
return -1;
}
getname=gethostbyname(name);//使用函数
if(getname==NULL)
{
printf("Get hostname failure\n");
return -2;
}
pptr=getname->h_addr_list;
ptr=inet_ntop(getname->h_addrtype,*pptr,buf,sizeof(buf));
printf("The standard name of %s is %s\n",name,getname->h_name);
printf("The alias of %s is %s\n",name,*(getname->h_aliases));
printf("The ip type of %s is %d\n",name,getname->h_addrtype);
printf("The ip length of %s is %d\n",name,getname->h_length);
printf("The ip address of %s is %s\n",name,ptr);
return 0;
}
编译运行结果如下,此时可通过运行得到的ip访问baidu
zhanghang@Ubuntu-14:~/C$ gcc gethostbyname_test.c
zhanghang@Ubuntu-14:~/C$ ./a.out -h www.baidu.com
The standard name of www.baidu.com is www.a.shifen.com
The alias of www.baidu.com is www.baidu.com
The ip type of www.baidu.com is 2
The ip length of www.baidu.com is 4
The ip address of www.baidu.com is 119.75.217.26