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

基本概念

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

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

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

image.png

步骤一:URL解析

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

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请求/响应的传输。