名词解释
URL:Uniform Resource Locator,统一资源定位符。 又叫网址 , 指以 http:// 开头的那一串东西 。
URI: Uniform Resource Identifier,统一资源标识符。 客户端会向服务器发送请求消息。 请求消息中包含的内容是“对什么” 和“进行怎样的操作” 两个部分。 其中相当于“对什么” 的部分称为 URI。相当于接下来“进行怎样的操作” 的部分称为方法,包括常用的GET、POST方法,和其他方法,如HEAD、OPTIONS、DELETE等。
HTTP协议:HTTP协议是超文本传输协议的缩写,英文是Hyper Text Transfer Protocol。它是从WEB服务器传输超文本标记语言(HTML)到本地浏览器的传送协议。即,HTTP 协议定义了客户端和服务器之间交互的消息内容和步骤 。
HTML:HTML 指超文本标记语言 (Hyper Text Markup Language), 是用来描述网页的一种语言。HTML 不是一种编程语言,而是一种标记语言,HTML 使用标记标签来描述网页。
知识拓展:HTML 是什么?
域名:Domain Name,是由一串用点分隔的名字组成的Internet上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位。
域名和URL的区别:
以 http://mail.163.com/index.html为例:
(1) http:// 是协议,也就是HTTP超文本传输协议,也就是网页在网上传输的协议。
(2) mai 是服务器名,代表着是一个邮箱服务器,所以是mail.
(3) 163.com 是域名,是用来定位网站的独一无二的名字。
(4) mail.163.com 是网站名,由服务器名+域名组成。
(5) “/” 指根目录,也就是说,通过网站名找到服务器,然后在服务器存放网页的根目录
- index.html:这个是根目录下的默认网页(大部分的默认网页都是index.html)
(7) http://mail.163.com/index.html 则是URL,统一资源定位符,全球性地址,用于定位网上的资源。
DNS:Domain Name System,网域名称系统。DNS是一个域名系统,是万维网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。
IP地址:IP 地址是一串 32 比特的数字,按照 8 比特( 1 字节)为一组分成 4 组,分别用十进制表示然后再用圆点隔开。 这组数字指定了设备的网络号和主机号。其中, 网络对应的号码是分配给整个子网的, 而主机号对应的号码是分配给子网中的计算机的, 这就是网络中的地址。 在组建网络时,用户可以用子网掩码决定网络号和主机号之间的分配关系。
子网掩码:是一 串与 IP 地址长度相同的 32 比特数字,其左边一半都是 1,右边一半都是0。其中,子网掩码为 1 的部分表示网络号, 子网掩码为 0 的部分表示主机号。此外,主机号部分的比特全部为 0 或者全部为 1 时代表两种特殊的含义。 主机号部分全部为 0 代表整个子网而不是子网中的某台设备;主机号部分全部为 1 代表向子网上所有设备发送包 即广播。
浏览器生成消息的过程
客户端生成HTTP请求消息 → 向DNS服务器查询Web服务器的IP地址 → 寻找相应的 DNS 服务器并获取 IP 地址
客户端生成HTTP请求消息
-
url组成:
-
浏览器解析url
(1). 客户端会根据HTTP协议,向服务器发送请求消息。请求消息由请求行、请求头、消息体组成。
请求消息中包含的内容是“对什么” 和“进行怎样的操作” 两个部分。其中相当于“对什么” 的部分称为 URI,相当于接下来“进行怎样的操作” 的部分称为方法。收到请求消息之后,Web 服务器会对其中的内容进行解析,通过 URI 和方法来判断“对什么”,“进行怎样的操作”,并根据这些要求来完成自己的工作,然后将结果存放在响应消息中,响应消息由状态行、消息头、消息体组成。
(2).在响应消息的开头有一个状态码, 它用来表示操作的执行结果是成功还是发生了错误。状态码后面就是头字段和网页数据。 响应消息会被发送回客户端, 客户端收到之后 浏览器会从消息中读出所需的数据并显示在屏幕上。 到这里 HTTP 的整个工作就完成了。
(3).由于每条请求消息中只能写 1 个 URI, 所以每次只能获取 1 个文件, 如果需要获取多个文件, 必须对每个文件单独发送 1 条请求。 比如 1个网页中包含 3 张图片, 那么获取网页加上获取图片, 一共需要向 Web 服务器发送 4 条请求。
向DNS服务器查询Web服务器的IP地址
1. 域名和 IP 地址
互联网和公司内部的局域网都是基于 TCP/IP 的思路来设计的,而TCP/IP 网络是通过 IP 地址来确定通信对象的, 因此不知道 IP 地址就无法将消息发送给对方。因此,在委托操作系统发送消息时,必须要先查询好对方的 IP 地址。
现在我们使用的方案是让人来使用名称,让路由器来使用 IP 地址。为了填补两者之间的障碍,需要有一个机制能够通过名称来查询 IP 地址,或者通过 IP 地址来查询名称,这样就能够在人和机器双方都不做出牺牲的前提下完美地解决问题。 这个机制就是 DNS。
2. 通过 DNS 查询 IP 地址
向 DNS 服务器发出查询, 也就是向 DNS 服务器发送查询消息, 并接收服务器返回的响应消息。 换句话说, 对于 DNS 服务器, 我们的计算机上一定有相应的 DNS 客户端, 而相当于 DNS 客户端的部分称为 DNS 解析器, 或者简称解析器。 通过 DNS 查询 IP 地址的操作称为域名解析, 因此负责执行解析( resolution) 这一操作的就叫解析器( resolver) 了 。
解析器实际上是一段程序, 它包含在操作系统的 Socket 库中 ,Socket 库是用于调用网络功能的程序组件集合。调用解析器后, 解析器会向 DNS 服务器发送查询消息, 然后 DNS 服务器会返回响应消息。 响应消息中包含查询到的 IP 地址, 解析器会取出 IP 地址, 并将其写入浏览器指定的内存地址中。
顺带一提, 向 DNS 服务器发送消息时, 我们当然也需要知道 DNS 服 务器的 IP 地址。 只不过这个 IP 地址是作为 TCP/IP 的一个设置项目事先设 置好的, 不需要再去查询了。 不同的操作系统中 TCP/IP 的设置方法也有差 异, Windows 中的设置如图 1.13 所示, 解析器会根据这里设置的 DNS 服 务器 IP 地址来发送消息。
3. 寻找相应的 DNS 服务器并获取 IP 地址
DNS 服务器中的所有信息都是按照域名以分层次的结构来保存 的。 层次结构这个词听起来可能有点不容易懂, 其实就类似于公司中的事 业集团、 部门、 科室这样的结构。 层次结构能够帮助我们更好地管理大量 的信息。DNS 中的域名都是用句点来分隔的, 比如 www.lab.glasscom.com, 这里的句点代表了不同层次之间的界限,在域名中,越靠右的位置表示其层级越高, 比如 www.lab.glasscom.com 这个域名如果按照公司 里的组织结构来说, 大概就是“com 事业集团 glasscom 部 lab 科的 www” 这样。 其中,相当于一个层级的部分称为域。 因此, com 域的下一层是 glasscom 域,再下一层是 lab 域,再下面才是 www 这个名字。
在前面的讲解中, 似乎 com、 jp 这些域( 称为顶级域) 就是最顶层了,但在互联网中, com 和 jp 的上面还有一级域, 称为根域。 如果要明确表示根域, 应该像 www.lab.glasscom.com. 这样在域名的最后再加上一个句点, 而这个最后的句点就代表根域。将根域的 DNS 服务器信息保 存在互联网中所有的 DNS 服务器中, 这样任何 DNS 服务器就都可以找到并访问根域 DNS 服务器了。
下面就来看一看DNS 服务器如何从上万台 DNS 服务器中找到目标服务器。
委托协议栈发送消息
发送数据是一系列操作相结合来实现的,和向 DNS 服务器查询 IP 地址的操作一样, 这里也需要使用 Socket 库中的程序组件。不过,查询 IP 地址只需要调用一个程序组件就可以了,而这里需要按照指定的顺序调用多个程序组件。
收发数据的操作分为若干个阶段, 可以大致总结为以下 4 个:
(1) 创建套接字( 创建套接字阶段)
(2) 将管道连接到服务器端的套接字上( 连接阶段)
(3) 收发数据( 通信阶段)
(4) 断开管道并删除套接字( 断开阶段)
这 4 个操作都是由操作系统中的协议栈来执行的,浏览器等应用程序并不会自己去做连接管道、放入数据这些工作,而是委托协议栈来代劳。使用 Socket 库来收发数据的操作过程如图 1.17 所示。
- 创建套接字阶段
首先, 服务器一方先创建套接字, 然后等待客户端向该套接字连接管道。 当服务器进入等待状态时, 客户端就可以连接管道了。
客户端 调用 socket 之后, 控制流程会转移到 socket 内部并执行创建套接字的操作, 完成之后控制流程又会被移交回应用程序。套接字创建完成后, 协议栈会返回一个描述符, 应用程序会将收到的描述符存放在内存中。
计算 机中会同时进行多个数据的通信操作,比如可以打开两个浏览器窗口, 同时访问两台 Web 服务器。这时,有两个数据收发操作在同时进行,也就需要创建两个不同的套接字。这个例子说明, 同一台计算机上可能同时存在多个套接字,在这样的情况下, 我们就需要一种方法来识别出某个特定的套接字, 这种方法就是描述符。
- 连接阶段:把管道接上去
委托协议栈将客户端创建的套接字与服务器那边的 套接字连接起来。应用程序通过调用 Socket 库中的名为 connect 的程序组 件来完成这一操作。这里的要点是当调用 connect 时,需要指定描述符、 服务器 IP 地址和端口号这 3 个参数。
(1) 描述符:应用程序用来识别套接字的机制
(2) IP 地址和端口号:客户端和服务器之间用来识别对方套接字的机制
客户端在创建套接字时,协议栈会为这个套接 字随便分配一个端口号 。 接下来, 当协议栈执行连接操作时,会将这个随便分配的端口号通知给服务器。描述符是用来在一台计算机内部识别套接字的机制, 而端口号是用来让通信的另一方能够识别出套接字的机制。其中,服务器上所使用的端口号是根据应用的种类事先规定好的,只要指定了事先规定好的端口号, 就可以连接到相应的服务器程序的套接字。
- 通信阶段:传递消息
当套接字连接起来之后,只要将数据送入套接字, 数据就会被发送到对方的套接字中。这个操作需要使用Socket 库 中的 write 程序组件。服务器执行接收操作后, 解析收到的数据内容,并执行相应的操作,向客户端返回响应消息。当消息返回后, 需要执行的是接收消息的操作。 接收消息的操作是通 过 Socket 库中的 read 程序组件委托协议栈来完成的
- 断开阶段:收发数据结束
浏览器收到数据之后, 收发数据的过程就结束了。 接下来, 调用 Socket 库的 close 程序组件进入断开阶段 最终, 连接在套接字之间的管道会被断开, 套接字本身也会被删除。
这就是 HTTP 的工作过程。 HTTP 协议将 HTML 文档和图片都作为单独的对象来处理, 每获取一次数据, 就要执行一次连接、 发送请求消息、 接收响应消息、 断开的过程。 因此, 如果一个网页中包含很多张图片, 就必须重复进行很多次连接、 收发数据、 断开的操作。 对于同一台服务器来 说, 重复连接和断开显然是效率很低的, 因此后来人们又设计出了能够在 一次连接中收发多个请求和响应的方法。 在 HTTP 版本 1.1 中就可以使用这种方法, 在这种情况下, 当所有数据都请求完成后, 浏览器会主动触发断开连接的操作。