距离上次更新本文已经过去了 236 天,文章部分内容可能已经过时,请注意甄别

面试总是考这个,虽然我能说出个大概,但总是卡壳,还是重新记录一下。

基本概念

首先要知道这里面会涉及到什么协议,以 HTTP 的网页为例,会涉及到下面这些协议

  • HTTP/HTTPS
  • TCP
  • IP
  • ARP
  • DNS
  • NAT

当然,更底层的还有路由选择协议 OSPF 等,但这些一般情况下不会考察到(除非你面试的是网络工程师相关岗位),所以能把上面的这些协议的步骤说清楚就基本够了。

image.png

步骤一:URL 解析

浏览器首先是需要解析你访问的 URL,从里面提取当前使用的网络协议(以 HTTP 协议为例),目标的域名,以及域名后的请求路径与参数。

plaintext
1
http(s)://<host>:<port>/<path>?<query>#<frag>

随后浏览器会将这里面的信息封装成一个 HTTP 请求报文。

假设你访问的是某个网页的主页,那么浏览器就会构造一个 GET 请求报文,去请求根路径下的 index.html 文件。

步骤二:DNS 解析

知道了域名,还需要知道这个域名对应的 IP 地址,才能发起网络请求。浏览器会进行 DNS 查询(基于 UDP),来找到域名的 IP 地址。

  • 查询浏览器本地缓存;
  • 查询 PC 主机本地缓存;
  • 查询主机 HOSTS 文件;
  • 本地缓存找不到,向默认 DNS 服务器(通常是 ISP 的 DNS 服务器)发起递归查询;
  • ISP 的 DNS 服务器使用迭代的方式依次从根域名服务器、顶级域名服务器…… 直到找到该域名映射的 IP 地址。
  • ISP 的 DNS 服务器向客户端返回 IP 地址(服务器一般有负载均衡,同一个域名每一次查询到的 IP 地址可能不一样)

DNS 是基于 UDP 的,底层依旧是 IP 协议,当前的主机一般是知道 DNS 服务器的 IP 地址的(可以手动配置公共 DNS 服务器,或者自动选择时默认 ISP 的 DNS 服务器),所以不存在还需要查询 DNS 服务器的 IP 地址的情况。

  • 如果找不到,会返回失败,此时浏览器会显示 DNS_PROBE_FINISHED_NXDOMAIN,提示用户该域名找不到 IP 地址(没有成功解析)
  • 如果找到了,浏览器会将这个域名和 IP 的对应关系放入自己的缓存,方便下一次请求。

本地的 DNS 缓存也会有一个过期计时器,避免目标域名和 IP 的映射关系发生变化。

步骤三:TCP 握手

现在我们知道目标主机的 IP 地址了,也知道端口号(HTTP 协议是 80 端口,HTTPS 是 443 端口),现在浏览器会调用系统接口,发起 TCP 三次握手的请求。下面的工作就是操作系统的网络协议栈来处理的了啦!

这里可能会追问为什么 TCP 握手是三次:三次握手是保证双方通信能力的最小握手次数,同时也一定程度上避免了一次和二次握手中客户端只需要发送一次 SYN 就能攻击服务器的情况。

image.png

TCP 的握手报文向下层 IP 层交付,IP 层封装源 IP 和目的服务器 IP(刚刚通过 DNS 获得的),并将 TCP 报文封装到 IP 报文的数据部分,向下层数据链路层交付。

数据链路层通过 ARP 协议查询 IP 地址对应的 MAC 地址:

  • 如果是家庭局域网,查询不到目的 IP 地址,主机会用默认的下一跳(一般是路由器)发送这个报文(后序还涉及到 NAT 协议);
  • 如果两个主机都在公网,发送端路由器进行路由查找,查询目标 IP 地址的目的网络,并转发到下一跳(随后都是公网路由器之间根据路由选择协议进行查表转发)。

注意,如果面试官没有要求,可以先忽略 IP 层的处理(只说通过 IP 协议来传输),这部分是最容易说岔的!

步骤四:服务器接收请求

服务器收到客户端发送的报文,从下往上交付,得到 HTTP 的 GET 请求,并根据请求中的路径和参数,将客户端需要的资源(html/js/css)封装并封装在 HTTP 响应报文中,传回客户端。

步骤五:客户端接收响应

客户端收到响应,解析 HTTP 响应中的数据,并交付浏览器进行页面渲染

此时根据双方的约定,决定保持链接还是终止 TCP 链接(终止需要进行 TCP 的四次挥手)

额外步骤:HTTPS 的 SSL 握手

如果是 HTTPS 协议,在正式发送请求之前,还需要进行 SSL 证书的握手。

引用:https://zhuanlan.zhihu.com/p/58955297

image.png

需要通过证书(非对称加密)握手,确定双方使用的对称加密密钥,再加密进行 HTTP 请求 / 响应的传输。