Linux网络编程--IP地址与域名解析(DNS)----- 博客不错.

https://blog.csdn.net/hnlyyk/article/details/48025621

 

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


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 */
1
2
3
4
5
6
7
8
函数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;
 }
--------------------- 
作者:奔跑吧,行者 
来源:CSDN 
原文:https://blog.csdn.net/hnlyyk/article/details/48025621 
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值