Linux网络编程--IP地址与域名解析(DNS)

在日常生活中,人们往往知道主机的域名而不知道主机的IP地址,而socket的API均基于IP地址,所以需要使用DNS域名解析服务器进行解析。
那么首先简单介绍一下DNS的原理,DNS服务器系统是按树形的结构构造,顶级域名服务器下分多个二级域名服务器,二级域名服务器下面又分多个下级域名服务器,每个服务器都下辖了一些主机,如图所示:
Linux网络编程--IP地址与域名解析(DNS)_第1张图片
那么一个主机是如何查询一个域名的IP地址呢?首先需要想本地的域名服务器查询,如果没有就向上级域名服务查询,如果二级的也查不到就会向顶级域名服务器查询,如果顶级的也查不到,那么就会返回错误。如图是 本地主机查询目标主机的DNS查询过程:
Linux网络编程--IP地址与域名解析(DNS)_第2张图片

Linux系统提供了获取主机信息的函数,gethostbyname(),gethostbyaddr(),两者都会用到一个结构体,结构体信息如下:

 struct hostent {
        char    *h_name;        /* official name of host */
        char    **h_aliases;    /* alias list */
        int     h_addrtype;     /* host address type */
        int     h_length;       /* length of address */
        char    **h_addr_list;  /* list of addresses */
  }
 #define h_addr h_addr_list[0] /* for backward compatibility */

函数gethostbyname和gethostbyaddr也具有不可重入性,返回结果保存在静态变量中,后者结果会覆盖前者,使用时要注意。
使用gethostbyname和gethostbyaddr的例子:

 #include <netdb.h>
 #include <string.h>
 #include <stdio.h>
 #include <sys/socket.h> 

 int main(int argc, char *argv[])
 {
    struct hostent *ht=NULL;

    /* 查询的主机域名 */
    char host[]="www.sina.com.cn";

 #if 1
    struct hostent *ht1=NULL, *ht2=NULL;
    char host1[]="www.sohu.com";
    /* 查询主机www.sina.com.cn */
    ht1 = gethostbyname(host);
    ht2 = gethostbyname(host1);//函数的不可重入性,前者结果已经被覆盖
    int j = 0;

 #else
    struct in_addr in;
    in.s_addr = inet_addr("60.215.128.140");
    ht = gethostbyaddr(&in, sizeof(in), AF_INET);
 #endif
 for(j = 0;j<2;j++){
    if(j == 0)
        ht = ht1;
    else
        ht =ht2;

    printf("----------------------\n");

    if(ht){
        int i = 0;
        printf("get the host:%s addr\n",host);  /* 原始域名 */
        printf("name:%s\n",ht->h_name);         /* 名称 */

        /*协议族AF_INET为IPv4或者AF_INET6为IPv6*/
        printf("type:%s\n",ht->h_addrtype==AF_INET?"AF_INET":"AF_INET6");

        /* IP地址的长度 */
        printf("legnth:%d\n",ht->h_length); 
        /* 打印IP地址 */
        for(i=0;;i++){
            if(ht->h_addr_list[i] != NULL){/* 不是IP地址数组的结尾 */
                printf("IP:%s\n",inet_ntoa((unsigned int*)ht->h_addr_list[i])); /*打印IP地址*/
            }   else{/*达到结尾*/
                break;  /*退出for循环*/
            }
        }

        /* 打印域名地址 */
        for(i=0;;i++){/*循环*/
            if(ht->h_aliases[i] != NULL){/* 没有到达域名数组的结尾 */
                printf("alias %d:%s\n",i,ht->h_aliases[i]); /* 打印域名 */
            }   else{/*结尾*/
                break;  /*退出循环*/
            }
        }
    }   
}
    return 0;
 }

你可能感兴趣的:(socket,网络编程,byname,DNS域名解析,gethostby)