网络是怎样连接的-读书笔记-浏览器生成消息
浏览器生成消息
本章解决的问题是,浏览器是如何工作的!
URL解析
首先输入给浏览器是是一个叫做URL的东西,就是我们经常用的网址,它告诉了要访问服务器上哪里的东西。
URL最一般的格式是:协议名-服务器域名-文件路径名。复杂一点就是如下这样,但很多是可以省略的:

具体的的格式是:

请求就对应着服务器内的一个文件,通常会是以html结尾。
然而很多时候我们都没有给出具体的文件,例如直接www.baidu.com/,就是访问这个Web服务器的根目录/,却没有给出具体的文件。我们通常会给每个目录设置一个默认访问文件,会使index.html或者default.htm。
更过分的是,连根目录都不给出来,直接www.baidu.com,这时候访问效果也是同上就是了~。如果发现访问的是目录,就会返回目录下的默认文件。
HTTP的基本思路
解决了访问什么东西的问题后,浏览器就要采取方法访问服务器,这种方法就是HTTP协议!

Client通过HTTP协议,发出请求消息,在其中给出自己的访问目标,以及采用的方法。请求消息分为两部分:
- URI(Uniform Resource Identifier):表示的是要对什么东西进行操作,一般分为两种,一是存放网页的文件,二是CGI程序(对 Web 服务器程序调用其他程序的规则所做的定义就是 CGI,而按照 CGI 规范来工作的程序就称为 CGI 程序)。
- 方法:有很多种,但是最常用的就是GET和POST,前者从网页上获取消息,对应的就是要访问文件;而后者是为了上传消息,对应的URI就是CGI程序。完整版的方法:
![]()
而Web服务器收到消息后,就会根据需要完成相应的工作,然后将结果存放在响应消息中,在响应消息的开头有一个状态码,它用来表示操作的执行结果是成功还是发生了错误(比如大家最经常见到的404 Not Found)。状态码后面就是头字段和网页数据。响应消息会被发送回客户端,客户端收到之后,浏览器会从消息中读出所需的数据并显示在屏幕上。到这里,HTTP的整个工作就完成了。
生成HTTP请求
以下就是HTTP请求的数据格式~


注意,每个请求只能写一个URI,因此一次只能获得一个文件,要获取多个文件就要发送多个请求。探寻需要用到什么样的文件是浏览器要做的事情,而Web服务器却不了解,它只关心要接受到什么样的请求,做出对应的操作。
向DNS服务器查询Web服务器的IP地址
尽管浏览器能够解析网址并生成 HTTP 消息,但它本身并不具备将消息发送到网络中的功能,因此这一功能需要委托操作系统来实现。
而在委托操作系统发送消息时,必须要提供的不是通信对象的域名,而是它的 IP 地址。因此,在生成 HTTP 消息之后,下一个步骤就是根据域名查询 IP 地址。
关于IP地址的简单介绍:

实际的 IP 地址是一串32 比特的数字,按照 8 比特(1 字节)为一组分成 4 组,分别用十进制表示然后再用圆点隔开。这就是我们平常经常见到的 IP 地址格式,但仅凭这一串数字我们无法区分哪部分是网络号,哪部分是主机号。在 IP 地址的规则中,网络号和主机号连起来总共是 32 比特,但这两部分的具体结构是不固定的。在组建网络时,用户可以自行决定它们之间的分配关系,因此,我们还需要另外的附加信息来表示 IP 地址的内部结构,这个附加信息就是子网掩码。子网掩码为 1 的部分表示网络号,子网掩码为 0 的部分表示主机号。
另外,主机号全0表整个子网,而主机号全1表对子网进行广播(所以有啥区别来着)。

我们不可能背下那么多的IP地址,所以要用一个名称来指代Web服务器,这种机制就是DNS。
我们向 DNS 服务器发出查询,也就是向 DNS 服务器发送查询消息,并接收服务器返回的响应消息。换句话说,对于 DNS 服务器,我们的计算机上一定有相应的 DNS 客户端,而相当于 DNS 客户端的部分称为 DNS 解析器,或者简称解析器。通过 DNS 查询 IP 地址的操作称为域名解析,因此负责执行解析(resolution)这一操作的就叫解析器(resolver)了,解析器实际上是一段程序,它包含在操作系统的 Socket 库中。
具体查询机制如下:

ps.发送消息这个操作并不是由解析器自身来执行,而是要委托给操作系统内部的协议栈来执行。这是因为和浏览器一样,解析器本身也不具备使用网络收发数据的功能。与访问别的域名不同的是,DNS服务器的IP早就设置在操作系统内了~。

DNS的查询消息包括:
- 域名:服务器、邮件服务器(邮件地址中 @ 后面的部分)的名称
- Class:早期DNS可能还给别的用,现在永远是代表互联网的IN。
- 记录类型:表示域名对应何种类型的记录。例如,当类型为 A(也就是Address) 时,表示域名对应的是 IP 地址;当类型为MX(Mail Exchange) 时,表示域名对应的是邮件服务器。对于不同的记录类型,服务器向客户端返回的信息也会不同。

但是现在有一个问题,互联网中的Web服务器内容IP地址肯定不能只保存在一个DNS服务器中,而同时互联网中有着数万台DNS服务器,肯定不可一个个找,采取的办法是树状层次结构管理。
这里引入了域的概念,而每个DNS服务器则对应一个域,一个域的子域收到其父域的管理。
DNS 中的域名都是用句点来分隔的,比如 www.lab.glasscom.com,这里的句点代表了不同层次之间的界限,就相当于公司里面的组织结构不用部、科之类的名称来划分,只是用句点来分隔而已。在域名中,越靠右的位置表示其层级越高,比如 www.lab.glasscom.com 这个域名如果按照公司里的组织结构来说,大概就是“com 事业集团 glasscom 部 lab 科的 www”这样。其中,相当于一个层级的部分称为域。因此,com 域的下一层是glasscom 域,再下一层是 lab 域,再下面才是 www 这个名字。最后一个域一般是服务器名字,所以基本所有服务器都叫做www?(大雾)。
一个域的信息是作为一个整体存放在 DNS 服务器中的,不能将一个域拆开来存放在多台 DNS 服务器中。在这种分层管理下,首先,将负责管理下级域的 DNS 服务器的 IP 地址注册到它们的上级 DNS 服务器中,然后上级 DNS 服务器的 IP 地址再注册到更上一级的 DNS 服务器中,以此类推。也就是说,负责管理 lab.glasscom.com 这个域的 DNS 服务器的 IP 地址需要注册到 glasscom.com 域的 DNS服务器中,glasscom.com 域的 DNS 服务器的 IP 地址又需要注册到 com域的 DNS 服务器中。这样,我们就可以通过上级 DNS 服务器查询出下级DNS 服务器的 IP 地址,也就可以向下级 DNS 服务器发送查询请求了。
最顶层的域叫做根域,是一个.,它负责管理的子域是.cn .jp .com这样的很顶级的域。而我们也是通过根域服务器来顺藤摸瓜的。下面是摸瓜的示意图:

一般我们不是直接访问根域服务器的,而是找一个最近的DNS服务器,存储在os的配置中,然后它会带我们去寻找根域服务器。你有这个域名吗?我没有,去找我老大吧,然后最后就会找到根域服务器,虽然根域服务器也没有,但是它会看到有一个com域是自己的小弟就会让你去找管理com的DNS服务器去了。
现实中的方式会有一点不同,例如:
- 不是所有的DNS服务器只保存一个域。他可以保存多个域,同级或者父子都行。
- 此外,有时候并不需要从最上级的根域开始查找,因为 DNS 服务器有一个缓存功能,可以记住之前查询过的域名。当要查询的域名不存在时,“不存在”这一响应结果也会被缓存。这样,当下次查询这个不存在的域名时,也可以快速响应。(类似CPU的快存?)
委托协议栈发送消息
向操作系统内部的协议栈发出委托时,需要按照指定的顺序来调用 Socket 库中的程序组件。Client和Service之间进行沟通,好像形成了一条数据管道一样。

但是管道不是无中生有的,而是建立出来的!建立管道的关键在于管道两端的数据出入口,这些出入口称为套接字。我们需要先创建套接字,然后再将套接字连接起来形成管道。当服务器进入等待状态的时候,客户端就可以连接管道了。客户端也会先创建一个套接字,然后从该套接字延伸出管道,最后管道连接到服务器端的套接字上。当双方的套接字连接起来之后,通信准备就完成了。接下来,就像我们刚刚讲过的一样,只要将数据送入套接字就可以收发数据了。
我们再来看一看收发数据操作结束时的情形。当数据全部发送完毕之后,连接的管道将会被断开。管道在连接时是由客户端发起的,但在断开时可以由客户端或服务器任意一方发起。其中一方断开后,另一方也会随之断开,当管道断开后,套接字也会被删除。到此为止,通信操作就结束了。
总结一下,就是有四个阶段,即创建-连接-收发-断开。

这些过程都是通过OS的接口函数来完成的。
第一步创建完Socket后,会返回一个描述符。因为计算机内可以同时存在多组网络通信,所以需要用描述符来识别相应的套接字。考虑在酒店寄存行李时的场景,酒店服务人员会给你一个号码牌,向服务人员出示号码牌,就可以取回自己寄存的行李,描述符的原理和这个差不多。
第二步就是连接Socket,把两边的管道连接起来,这是调用connect组件完成的,这里的要点是当调用 connect 时,需要指定描述符、服务器 IP 地址和端口号这 3 个参数。关于端口号的解释是这样的:IP地址实际上就是一个公司的电话,你能联系到公司,但是要具体某个部门,你还要给出部门号。部门号是大家都知道的事情,哪个部门会做什么样的工作。落实下来就是 Web 是 80 号端口,电子邮件是 25 号端口。
第三步就是通信,将数据送入到套接字中,对方就会接收到相关的消息,这个操作用的是Socket库的read和write组件。
第四步是断开,调用 Socket 库的 close 程序组件进入断开阶段。连接在套接字之间的管道会被断开,套接字本身也会被删除。
总结:到这里,浏览器通过URL连入Web服务器的工作都介绍完了,后面就是更底层的方法~,即TCP协议等。


浙公网安备 33010602011771号