文章目录
- 2.1 IP地址的基本知识
- 2.2 域名和IP地址共用理由
- 2.3 DNS本质是什么
- 2.4 浏览器如何获取IP
- 2.5 DNS解析器内部工作原理
2.1 IP地址的基本知识
浏览器能够解析网址并生成HTTP消息,但并不具备将消息发送到网络中的功能,因此这一功能需要委托操作系统来实现,而想要进行这一操作,我们必须知道是通信对象服务器域名对应的IP地址;
我们先了解一下局域网网络结构:由一些小的子网,通过路由器连接起来组成一个大的网络;这里的子网可以理解为用集线器连接起来的几台计算机为单位的团体,我们将它称为子网。将子网通过路由器连接起来,就形成了一个网络;
发送者发出的消息首先经过子网中的集线器,转发到距离发送者最近的路由器上。接下来,路由器会根据消息的目的地判断下一个路由器的位置,然后将消息发送到下一个路由器,即消息再次经过子网内的集线器被转发到下一个路由器,循环往复,直到找到目的地;
这里有个小问题,路由器是怎么知道发送消息的下一个目的地的呢?
在网络中,所有的设备都会被分配一个地址.这个地址就相当于现实中某条路上的“××号××室”;其中“号”对应某个子网(整体)的,而“室”对应某个子网中的计算机,这就是网络中的地址(IP). “号”对应的号码称为网络号,“室”对应的号码称为主机号,这个地址的整体称为IP地址,通过IP地址我们可以判断出访问对象服务器的位置,从而将消息发送到服务器。
实际的IP地址是一串32比特的数字,按照8比特(1字节)为一组分成4组,分别用十进制表示然后再用圆点隔开(称为点分十进制)。这就是我们平常经常见到的IP地址格式,但仅凭这一串数字我们无法区分哪部分是网络号,哪部分是主机号,因此我们需要另外的附加信息(子网掩码);
子网掩码的格式如下图所示,是一串与IP地址长度相同的32比特数字,其左边都是1,右边都是0。为1的部分的位置在ip地址中表示网络号,为0的部分的位置在ip地址中表示主机号;
子网掩码既可以用点分十进制表示,也可以用比特位中1的数目表示
IP地址的主机号
- 全0:表示整个子网
- 全1:表示向子网上所有设备发送包,即广播
子网掩码表示网络号与主机号之间的边界。在本例中,这个边界与字节的边界是正好吻合的,也就是正好划分在句点的位置上,实际上也可以划分在字节的中间位置
2.2 域名和IP地址共用理由
使用域名
是为了方便人类理解,因为人类相对于数字表示来说,更喜欢文字记忆;举个例子,这里有农业公司,商业公司,网络公司,贸易公司,国家银行等五个样例,通过其名字就能大概猜出其背后所做的业务;但若是给他们分别起数字名:111,222,333,444,555,是不是就会感觉很别扭?
使用IP
是为了方便计算机,计算机并不明白文字到底什么意思,它只知道对数字进行计算;同时使用IP对计算机来说也更加节省空间,随便一个域名可能就十几二十几个字节,但IP始终只有四个字节;
为了填补两者之间的障碍,需要有一个机制能够通过名称来查询IP地址,或者通过IP地址来查询名称,这样就能够在人和机器双方都不做出牺牲的前提下完美地解决问题。这个机制就是DNS(Domain Name System)
2.3 DNS本质是什么
浏览器向DNS服务器发出查询,也就是向DNS服务器发送查询消息,并接收服务器返回的响应消息(通过域名解析出来的IP地址);既然有了DNS服务器,那么就一定有DNS客户端,这里简称解析器,通过DNS查询ip地址的操作称为 域名解析 ,而负责这执行解析(resolution)操作的就称为解析器(resolver)了,而解析器实际上是一段程序,它包含在操作系统的Socket库中。
首先,库到底是什么东西呢?
库就是一堆通用程序组件的集合,其他的应用程序都需要使用其中的组件。库有很多好处。首先,使用现成的组件搭建应用程序可以节省编程工作量;其次,多个程序使用相同的组件可以实现程序的标准化,而解析器就是这个Socket库中的其中一种程序组件。
Socket库是用于调用网络功能的程序组件集合。
2.4 浏览器如何获取IP
浏览器本身也是一个程序软件,因此想要获取IP地址,那么就在程序中调用DNS解析器的程序名称就行(gethostbyname
),代码结构大致如下:
<浏览器程序名>(相关参数){
...
...
<某个变量或者内存接收该程序返回的内容> = gethostbyname("你所想查询的域名");
...
...
}
调用解析器后,解析器会向DNS服务器发送查询消息,然后DNS服务器会返回响应消息。响应消息中包含查询到的IP地址,解析器会取出IP地址,并将其写入浏览器指定的内存地址中。然后浏览器就可以得到域名所对应的IP地址了;
2.5 DNS解析器内部工作原理
当浏览器调用DNS解析器时候,程序的控制流程就开始转移,控制流程转移指的是由于调用了其他程序,原本运行的程序进入暂停状态,而被调用的程序开始运行,如下图(注意箭头深浅和标记的执行顺序):
当控制流程转移到解析器后,解析器会生成要发送给DNS服务器的查询消息。这个过程与浏览器生成要发送给Web服务器的HTTP请求消息的过程类似,解析器会根据DNS的规格,生成一条表示“请告诉我www.lab.glasscom.com的IP地址的数据,并将它发送给DNS服务器(上图③)。发送消息这个操作并不是由解析器自身来执行,而是要委托给操作系统内部的协议栈[插图]来执行。这是因为和浏览器一样,解析器本身也不具备使用网络收发数据的功能。
解析器调用协议栈后,控制流程会再次转移,协议栈会执行发送消息的操作,然后通过网卡将消息发送给DNS服务器(上图④⑤)。当DNS服务器收到查询消息后,它会根据消息中的查询内容进行查询。查询后的IP地址会被写入响应消息并返回给客户端(上图⑥)。接下来,消息经过网络到达客户端,再经过协议栈被传递给解析器(上图⑦⑧),然后解析器读取出消息取出IP地址,并将IP地址传递给应用程序(上图⑨)。
计算机的内部结构就是这样一层一层的。也就是说,很多程序组成不同的层次,彼此之间分工协作。当接到上层委派的操作时,本层的程序并不会完成所有的工作,而是会完成一部分工作,再将剩下的部分委派到下层来完成。
顺带一提,向DNS服务器发送消息时,我们当然也需要知道DNS服务器的IP地址。只不过这个IP地址是作为TCP/IP的一个设置项目事先设置好的,不需要再去查询了。不同的操作系统中TCP/IP的设置方法也有差异,Windows中的设置如图所示,解析器会根据这里设置的DNS服务器IP地址来发送消息。
====================================上一章====================================