网络编程域名解析函数gethostbyname()的使用

我们通常在网页上访问一个网址,例如访问百度时,我们通常是输入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

猜你喜欢

转载自blog.csdn.net/qq_43260665/article/details/84201567