输入网址到网页显示的过程
# 解析URL生成HTTP请求
- 首先浏览器做的第一步工作就是要对 URL 进行解析,从而产生发送给 Web 服务器的请求信息。
- 对 URL 进行解析之后,浏览器确定了 Web 服务器和文件名,接下来就是根据这些信息来生成 HTTP 请求消息了。
# 域名解析-DNS
通过浏览器解析 URL 并生成 HTTP 消息后,需要委托操作系统将消息发送给 Web 服务器。
但在发送之前,还有一项工作需要完成,那就是查询服务器域名对应的 IP 地址,因为委托操作系统发送消息时,必须提供通信对象的 IP 地址。所以,有一种服务器就专门保存了 Web 服务器域名与 IP 的对应关系,它就是 DNS 服务器。
其实,在发送DNS查询之前,浏览器会根据输入的URL地址,去查找域名是否被本地DNS缓存,不同浏览器对DNS的设置不同,如果浏览器缓存了想访问的URL地址,那就直接返回IP地址。如果没有缓存,浏览器就会发起系统调用来查询本机hosts文件是否有配置ip地址,如果找到,直接返回。如果找不到,就向网络中发起一个DNS域名解析请求。
域名解析的工作流程
DNS 域名解析的过程蛮有意思的,整个过程就和我们日常生活中找人问路的过程类似,只指路不带路,这是一种迭代查询的方式。还有一种递归查询方式,但是这种方式只有根域名服务器无法告知本地DNS服务器下一步需要访问哪个顶级域名服务器时才会使用。
# 建立TCP连接
HTTP 是基于 TCP 协议传输的,所以客户机需要和目标服务器建立TCP连接,这里要经过三次握手的过程。
# 三次握手
# TCP分割数据
如果 HTTP 请求消息比较长,超过了 MSS 的长度,这时 TCP 就需要把 HTTP 的数据拆解一块块的数据发送,而不是一次性发送所有数据。
MTU:一个网络包的最大长度,以太网中一般为 1500 字节。
MSS:除去 IP 和 TCP 头部之后,一个网络包所能容纳的 TCP 数据的最大长度。
数据会被以 MSS 的长度为单位进行拆分,拆分出来的每一块数据都会被放进单独的网络包中。也就是在每个被拆分的数据加上 TCP 头信息,然后交给 IP 模块来发送数据。
# TCP报文生成
TCP 协议里面会有两个端口,一个是浏览器监听的端口(通常是随机生成的),一个是 Web 服务器监听的端口(HTTP 默认端口号是 80**, HTTPS 默认端口号是** 443)。
在双方建立了连接后,TCP 报文中的数据部分就是存放 HTTP 头部 + 数据,组装好 TCP 报文之后,就需交给下面的网络层处理。
# IP层
TCP 模块在执行连接、收发、断开等各阶段操作时,都需要委托 IP 模块将数据封装成网络包发送给通信对象。
生成了 IP 头部之后,接下来网络包还需要在 IP 头部的前面加上 MAC 头部。
# 网卡-数据链路层
IP 生成的网络包只是存放在内存中的一串二进制数字信息,没有办法直接发送给对方。因此,我们需要将数字信息转换为电信号,才能在网线上传输,也就是说,这才是真正的数据发送过程。
负责执行这一操作的是网卡,要控制网卡还需要靠网卡驱动程序。
网卡驱动从 IP 模块获取到包之后,会将其复制到网卡内的缓存区中,接着会其开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列。
- 最后网卡会将包转为电信号,通过网线发送出去。
# 路由器
在网络包传输的过程中,源 IP 和目标 IP 始终是不会变的,一直变化的是 MAC 地址,因为需要 MAC 地址在以太网内进行两个设备之间的包传输。
# 服务端接收数据包
数据包抵达服务器后,服务器会先扒开数据包的 MAC 头部,查看是否和服务器自己的 MAC 地址符合,符合就将包收起来。
接着继续扒开数据包的 IP 头,发现 IP 地址符合,根据 IP 头中协议项,知道自己上层是 TCP 协议。
于是,扒开 TCP 的头,里面有序列号,需要看一看这个序列包是不是我想要的,如果是就放入缓存中然后返回一个 ACK,如果不是就丢弃。TCP头部里面还有端口号, HTTP 的服务器正在监听这个端口号。
于是,服务器自然就知道是 HTTP 进程想要这个包,于是就将包发给 HTTP 进程。
# 响应
服务器的 HTTP 进程看到,原来这个请求是要访问一个页面,于是就把这个网页封装在 HTTP 响应报文里。
HTTP 响应报文也需要穿上 TCP、IP、MAC 头部,不过这次是源地址是服务器 IP 地址,目的地址是客户端 IP 地址。
# 客户端接收响应并渲染页面
客户端收到了服务器的响应数据包后,同样也非常的高兴,客户能拆快递了!
于是,客户端开始扒皮,把收到的数据包的皮扒剩 HTTP 响应报文后,交给浏览器去渲染页面,一份特别的数据包快递,就这样显示出来了!
# 断开连接
最后,客户端要离开了,向服务器发起了 TCP 四次挥手,至此双方的连接就断开了。
# 参考
https://mp.weixin.qq.com/s/iSZp41SRmh5b2bXIvzemIw (opens new window)