博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
域名及网络地址
阅读量:2177 次
发布时间:2019-05-01

本文共 3676 字,大约阅读时间需要 12 分钟。

域名系统

DNS(Domain Name System :域名系统)是对IP地址和域名进行相互转换的系统,其核心是DNS服务器。

 

什么是域名

提供网络服务的服务器端也是通过IP地址区分的,但几乎不可能以非常难记的IP地址形式交换服务器端地址信息。

 

DNS服务器

在浏览器地址栏中输入Naver网站的IP地址222.122.195.5即可浏览Naver网站主页。但我们通常输入网站的域名www.naver.com访问网站。

 

域名是赋予服务器端的虚拟地址,而非实际地址。因此,需要将虚拟地址转化为实际地址。那如何将域名变为IP地址呢?

DNS服务器担此重任,可以向DNS服务器请求转换地址。所有计算机中都记录着默认DNS服务器地址,就是通过这个默认DNS服务器得到相应域名的IP地址信息。在浏览器地址栏中输入域名后,浏览器通过默认DNS服务器获取该域名对应的IP地址信息,真正接入该网站。

 

ping 

这样可知道某一域名对应的IP地址。

先执行命令nslookup,再输入server可以获得计算机中注册的默认DNS服务器地址。

 

 

计算机内置的默认DNS服务器并不知道网络上所有域名的IP地址信息。若该DNS服务器无法解析,则会询问其他DNS服务器,并提供给用户

                                    

 

上图展示了默认DNS服务器无法解析主机询问的域名IP地址时的应答过程:

    默认DNS服务器收到无法解析的请求时,向上级DNS服务器询问,通过这种方式逐级向上传递信息,到达顶级DNS服务器——根DNS服务器时,它知道向哪个DNS服务器访问。向下级DNS服务器传递解析请求,得到IP地址后原路返回,最后将解析的IP地址传递到发起请求的主机。

DNS就是这样层次化管理的一种分布式数据库系统。

 

 

IP地址和域名之间的转换

 

为什么使用域名?

IP地址比域名发生变更的概率要高,所以利用IP地址编写程序并非上策。域名注册后可能永久不变,因此利用域名编写程序会好一些。每次运行程序时根据域名获取IP地址,再接入服务器,这样程序就不会依赖于服务器IP地址了。所以说程序中需要IP地址和域名之间的转换函数。

解析器和名字服务器

常见的解析器函数:gethostbyname和gethostbyaddr,前者把主机名映射称IPv4地址,后者执行相反的映射。

下图展示了应用程序,解析器和名字服务器之间的典型关系:    

                    

 

利用域名获取IP地址

使用以下函数可以通过传递字符串格式的域名获取IP地址。

 

此函数传递域名字符串,返回域名对应的IP地址。返回时,地址信息装入hostent结构体。结构体定义如下:

struct hostent{    char * h_name;                  //official name    char ** h_aliases;              //alias list    int h_addrtype;                 //host address type    int h_length;                   //address length    char ** h_addr_list;            //address list}

域名转换只需关注h_addr_list。

结构体各成员:

h_name: 该变量中存放官方域名。官方域名代表某一主页。

h_aliases: 可以通过多个域名访问 同一主页,同一IP可以绑定多个域名。

h_addrtype: gethostbyname函数不仅支持IPv4,也支持IPv6。通过此变量获取保存在h_addr_list的IP地址的地址族信息。

h_length:保存IP地址的长度。IPv4是4字节,IPv6是16字节。

h_addr_list: 最重要的成员,整数形式保存域名对应的IP地址。用户较多的网站有可能分配多个IP给同一域名,利用多个服务器进行负载均衡。

 

调用gethostbyname函数后返回hostent结构体的变量结构如下图:

                                        

 

/* gethostbyname函数的应用:并说明hostent结构体变量的特性 */#include
#include
#include
#include
#include
#include
void error_handling(char *message){ fputs(message,stderr); fputc('\n',stderr); exit(1);}int main(int argc,char *argv[]){ int i; struct hostent *host; if (argc != 2) { printf("Usage: %s
\n",argv[0]); exit(1); } host = gethostbyname(argv[1]); if (!host) error_handling("gethostbyname() error!"); printf("Official name:%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++) //输出IP地址信息 printf("IP addr %d: %s \n",i+1,inet_ntoa(*(struct in_addr*)host->h_addr_list[i])); return 0;}

运行结果:

 

 

若只看hostent结构体的定义,结构体成员h_addr_list指向字符串指针数组。但字符串指针数组中的元素实际指向的是in_addr结构体变量地址而非字符串。如图所示:

 

 

利用IP地址获取域名  

 gethostbyaddr函数利用IP地址获取域相关信息。

 

  

/* gethostbyaddr函数的应用 */#include
#include
#include
#include
#include
#include
void error_handling(char *message){ fputs(message,stderr); fputc('\n',stderr); exit(1);}int main(int argc,char *argv[]){ int i; struct hostent *host; struct sockaddr_in addr; if (argc != 2) { printf("Usage: %s
\n",argv[0]); exit(1); } memset(&addr,0,sizeof(addr)); addr.sin_addr.s_addr = inet_addr(argv[1]); host = gethostbyaddr((char*)&addr.sin_addr,4,AF_INET); if (!host) error_handling("gethostbyaddr() error!"); printf("Official name:%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++) //输出IP地址信息 printf("IP addr %d: %s \n",i+1,inet_ntoa(*(struct in_addr*)host->h_addr_list[i])); return 0;}

先通过ping获得Google的IP地址,并利用此信息运行示例:

 

完 

你可能感兴趣的文章
深入理解JVM虚拟机9:JVM监控工具与诊断实践
查看>>
深入理解JVM虚拟机10:JVM常用参数以及调优实践
查看>>
深入理解JVM虚拟机11:Java内存异常原理与实践
查看>>
深入理解JVM虚拟机12:JVM性能管理神器VisualVM介绍与实战
查看>>
深入理解JVM虚拟机13:再谈四种引用及GC实践
查看>>
Spring源码剖析1:Spring概述
查看>>
Spring源码剖析2:初探Spring IOC核心流程
查看>>
Spring源码剖析3:Spring IOC容器的加载过程
查看>>
Spring源码剖析4:懒加载的单例Bean获取过程分析
查看>>
Spring源码剖析5:JDK和cglib动态代理原理详解
查看>>
Spring源码剖析6:Spring AOP概述
查看>>
Spring源码剖析7:AOP实现原理详解
查看>>
Spring源码剖析8:Spring事务概述
查看>>
Spring源码剖析9:Spring事务源码剖析
查看>>
重新学习Mysql数据库1:无废话MySQL入门
查看>>
探索Redis设计与实现2:Redis内部数据结构详解——dict
查看>>
探索Redis设计与实现3:Redis内部数据结构详解——sds
查看>>
探索Redis设计与实现4:Redis内部数据结构详解——ziplist
查看>>
探索Redis设计与实现6:Redis内部数据结构详解——skiplist
查看>>
探索Redis设计与实现5:Redis内部数据结构详解——quicklist
查看>>