了解 HTTP 协议
1. 浏览器背后的故事
网站上的域名其实对应的是服务器的 IP。因为 IP 比较难记,所以就先访问 DNS 服务器来获取域名所映射的 IP,然后发送请求到 Web 服务器。
HTTP 协议
超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言(HTML)文档从 Web 服务器传送到客户端的浏览器。土话:传输 HTML 需要遵守的规则。
HTTP 是一个属于应用层的面向对象的协议,由于其便捷、快速的方式,适用于分布式超媒体信息系统。它于 1990 年提出,经过几年的使用与发展,得到不断地完善和扩展。
2. HTTP 协议的前世今生
3. 透过 TCP/IP 看 HTTP
- HTTP 协议是构建在 TCP/IP 协议之上的,是 TCP/IP 协议的一个子集
- 为了更好的理解 HTTP 协议,我们先了解一下 TCP/IP 的相关知识
TCP/IP 协议族
- TCP/IP 协议其实是一系列与互联网相关联的协议集合起来的总称
- 分层管理是 TCP/IP 的重要特征
TCP/IP 协议族分层
TCP/IP 协议族是由一个四层协议组成的系统,这四层分别为:应用层、传输层、网络层和数据链路层
应用层
应用层一般是我们编写的应用程序,决定了向用户提供的应用服务。应用层可以通过系统调用与传输层进行通信。
如:FTP、DNS、HTTP 等。
传输层
传输层通过系统调用向引用层提供处于网络连接中的两台计算机之间的数据传输功能。
在传输层有两个性质不同的协议:TCP 和 UDP
TCP 是面向连接的,UDP 是无连接的,所以 TCP 效率较低,但是可靠性较高。
网络层
网络层用来处理在网络上流动的数据包,数据包是网络传输的最小数据单位。该层规定了通过怎样的路径(传输路线)到达对方计算机,并把数据包传输给对方。
链路层
链路层用来处理连接网络的硬件部分,包括控制操作系统、硬件设备驱动、NIC (Network Interface Card,网络适配器)以及光纤等物理可见部分。硬件上的范畴均在链路层的作用范围之内。
数据包的封装过程
HTTP 数据传输过程
发送端发送数据时,数据会从上层传输到下层,且每经过一层都会被打上该层的头部信息。而接收端接收数据时,数据会从下层传输到上层,传输前会把下层的头部信息删除。
传输层-TCP三次握手
使用 TCP 协议进行通信的双方必须先建立连接,然后才能开始传输数据。为了确保连接双方可靠性,在双方建立连接时,TCP 协议采用了三次握手策略。
-
第一次握手:客户端发送带有 SYN 标志的连接请求报文段,然后进入 SYN_SEND 状态,等待服务端的确认。
接收到了客户端的请求。服务端确认了,服务端接收能力正常,客户端发送正常。
-
第二次握手:服务端接收到客户端的 SYN 报文段后,需要发送 ACK 信息对这个 SYN 报文段进行确认。同时,还要发送自己的 SYN 请求信息。服务端会将上述的信息放到一个报文段 (SYN + ACK 报文段)中,一并发送给客户端,此时服务端将会进入 SYN_RCEV 状态。
接收到了服务端对之前的确认和服务端自己的请求。客户端确认:服务端接收正常,发送正常。客户端自己发送正常,接收正常。但服务端目前只知道服务端接收能力正常,客户端发送正常。
-
第三次握手:客户端接收到服务端的 SYN + ACK 报文段后,会向服务端发送 ACK 确认报文段,这个报文段发送完毕后,客户端和服务端都进入 ESTABLISHED 状态,完成 TCP 三次握手。
接收到了客户端对之前服务单发送信息的的确认。服务端确认了,客户端发送接收正常,服务端发送接收正常。
综上所述,所以需要三次握手。
TCP 四次挥手
断开一个 TCP 连接则需要“四次挥手”:
- 客户端-发送一个 FIN,用来关闭客户端到服务器的数据传送
- 服务器-收到这个 FIN,它发回一 个 ACK,确认序号为收到的序号加 1 。和 SYN 一样,一个 FIN 将占用一个序号
- 服务器-关闭与客户端的连接,发送一个 FIN 给客户端
- 客户端-发回 ACK 报文确认,并将确认序号设置为收到序号加 1
任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了 TCP 连接。
举个例子:A 和 B 打电话,通话即将结束后,A 说“我没啥要说的了”,B 回答“我知道了”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话,于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”,A 回答“知道了”,这样通话才算结束。
4. DNS 域名解析
通常我们访问一个网站,使用的是主机名或者域名来进行访问的。因为相对于 IP 地址(一组纯数字),域名更容易让人记住。但 TCP/IP 协议使用的是 IP 地址进行访问的,所以必须有个机制或服务把域名转换成 IP 地址。DNS 服务就是用来解决这问题的,它提供域名到 IP 地址之间的解析服务。
DNS 解析简要过程
要访问一个网址,先访问 DNS 服务器,然后服务器返回对应的 IP 地址。客户端获取到 IP 地址后去发送请求,即可访问到 Web 服务器。
DNS服务器解析域名的过程:
-
⾸先会在缓存中查找对应的IP地址,如果查找到直接返回,若找不到继续下⼀步
-
将请求发送给本地DNS服务器,在本地域名服务器缓存中查询,如果查找到,就直接将查找结果返回,若找不到继续下⼀步
-
本地DNS服务器向根域名服务器发送请求,根域名服务器会返回⼀个所查询域的顶级域名服务器地址
-
本地DNS服务器向顶级域名服务器发送请求,接受请求的服务器查询⾃⼰的缓存,如果有记录,就返回查询结果,如果没有就返回相关的下⼀级的权威域名服务器的地址
-
本地DNS服务器向权威域名服务器发送请求,域名服务器返回对应的结果
-
本地DNS服务器将返回结果保存在缓存中,便于下次使⽤
-
本地DNS服务器将返回结果返回给浏览器
⽐如要查询 www.baidu.com 的 IP 地址,⾸先会在缓存中查找是否有该域名的缓存,如果不存在就将请求发送到本地的 DNS 服务器中,本地DNS服务器会判断是否存在该域名的缓存,如果不存在,则向根域名服务器发送⼀个请求,根域名服务器返回负责 .com 的顶级域名服务器的 IP 地址的列表。然后 本地 DNS 服务器再向其中⼀个负责 .com 的顶级域名服务器发送⼀个请求,负责 .com 的顶级域名服务器返回负责 .baidu 的权威域名服务器的 IP 地址列表。然后本地 DNS 服务器再向其中⼀个权威域名服务器发送⼀个请求,最后权威域名服务器返回⼀个对应的主机名的 IP 地址列表。
域名缓存
上面讲解的是域名服务器之间的 DNS 查询请求过程,但实际上,每个时刻都有无数网民要上网,那每次都去访问本地域名服务器去获取 IP 地址显然是不实际的。解决方法就是使用缓存保存域名和 IP 地址的映射。
计算机中 DNS 记录在本地有两种缓存方式:浏览器缓存和操作系统缓存。
- 浏览器缓存:浏览器在获取网站域名的实际 IP 地址后会对其进行缓存,减少网络请求的损耗。每种浏览器都有一个固定的 DNS 缓存时间,如 Chrome 的过期时间是 1 分钟,在这个期限内不会重新请求 DNS
- 操作系统缓存:操作系统的缓存其实是配置的 hosts 文件。
首先搜索浏览器的 DNS 缓存,缓存中维护一张域名与 IP 地址的对应表。若没有命中,则继续搜索操作系统的 DNS 缓存。
迭代查询与递归查询
转发模式使用的递归查询
实际上,DNS解析是⼀个包含迭代查询和递归查询的过程。
-
递归查询指的是查询请求发出后,域名服务器代为向下⼀级域名服务器发出请求,最后向⽤户返回查询的最终结果。使⽤递归查询,⽤户只需要发出⼀次查询请求。
-
迭代查询指的是查询请求后,域名服务器返回单次查询的结果。下⼀级的查询由⽤户⾃⼰请求。使⽤迭代查询,⽤户需要发出多次的查询请求。
⼀般我们向本地 DNS 服务器发送请求的⽅式就是递归查询,因为我们只需要发出⼀次请求,然后本地 DNS 服务器返回给我们最终的请求结果。
⽽本地 DNS 服务器向其他域名服务器请求的过程是迭代查询的过程,因为每⼀次域名服务器只返回单次查询的结果,下⼀级的查询由本地 DNS 服务器⾃⼰进⾏。
5. 回溯 HTTP 事务处理过程
大概过程
当客户端访问 Web 站点时,首先会通过 DNS 服务查询到域名的 IP 地址,然后浏览器生成 HTTP 请求,并通过 TCP/IP 协议发送给 Web 服务器。 Web 服务器接收到请求后会根据请求生成响应内容,并通过 TCP/IP 协议返回给客户端。
细节过程
6. 在浏览器中输入 url 地址 ->> 显示主页的过程
总体来说分为以下几个过程:
- DNS 解析
- TCP 连接
- 发送 HTTP 请求
- 服务器处理请求并返回 HTTP 报文
- 浏览器解析渲染页面
- 连接结束