❶ 当在浏览器输入一个 URL 后敲下回车, 浏览器首先会根据这里的域名查询对应的 IP 地址;
- 先查浏览器自身的缓存;
- 查询 hosts 文件;
- 查询 DNS 服务器.
❷ 浏览器构造一个 HTTP 请求, 并且这个请求中就包含着域名信息;
❸ 浏览器调用操作系统的 Socket api, 把 HTTP 数据交给 TCP 来处理, 这时候 TCP 协议就需要构造一个 TCP 数据报;
- 在发送 TCP 数据报之前, 需要先进行三次握手建立连接, 这里的三次握手就涉及到 SYN, ACK, 并且同样会经过网络层, 数据链路层, 物理层, 并依次进行封装, 到达端服务器之后再进行分用;
- 进行数据传输, 发送方会把这个 TCP 数据进一步的交给 IP 协议进行再一次的封装.
❹ 网络层把 TCP 数据报封装成一个或者多个 IP 数据报, 进一步进行封装, 然后把数据交给数据链路层;
❺ 数据链路层会把这个数据再封装成以太网数据帧; 在构造帧头的时候就需要根据 IP 映射到 MAC 地址, 这个构造过程就依赖了 ARP 协议; 然后将数据再交给物理层;
❻ 物理层将数据转换成电信号, 继续传输;
❼ 电信号通过网线或者光纤到达下一个路由器, 路由器就会针对收到的数据进行分用;
- 物理层将数据交给数据链路层, 数据链路层开始解析并将帧头和帧尾剥离出来, 得到网络层数据报, 然后交给网络层;
- 这时路由器拿到了网络层的 IP 数据报, 取出其中的目的 ip 并查询路由表, 找到下一个传输的目标, 进一步找到下一个传输目标的 mac 地址;
- 重新进行封装, 也就是再次将数据交给数据链路层和物理层, 这里的源 mac 和目的 mac 就已经发生改变了.
❽ 数据到达接收方也就是服务器端, 在服务器端进行分用并层层解析;
- 物理层将光电信号转成以太网数据帧, 交给数据链路层;
- 数据链路层解析出 IP 数据报, 交给网络层, 注意这里会涉及到 CRC 检验, 如果发现校验和不对, 就会直接丢弃;
- IP 协议再进行解析, 解析出一个 TCP 数据报, IP 报头里包含着协议类型;
- 根据 TCP 数据报中的端口号, 找到对应的进程. 将数据放入到对应的 Socket 的接收缓冲区里.
❾ 应用程序调用对应的 Socket api, 从 TCP 接收缓冲区中读取数据;
- 应用程序将数据按照 HTTP 协议来解析, 获取其中的 URL ;
- 根据 URL 中指定的路径获取到根路径.
❿ 服务器会对这个路径进行配置, 映射到一个具体的 html 中, 服务器就会读取这个文件, 把这个文件的内容构造成一个 HTTP 响应数据, 然后再调用 Socket api 进行发送;
⓫ 重复上述 4-6 步骤封装的过程, 服务器发送的响应数据也要进行层层封装, 最后变成一个物理层上传输的光电信号; 然后将这个光电信号发送到下一个路由器;
⓬ 路由器接收到光电信号后, 路由器还是重复上面步骤 7-8 分用的过程, 解析到 IP 这一层, 取出其中的 IP, 再次查询路由表, 找到下一个设备在哪, 然后再进行封装数据;
⓭ 重复上述过程, 依次进行转发, 最终到达用户的主机;
⓮ 用户主机重复上面分用的过程, 依次把数据取出来, 交给应用程序;
⓯ 浏览器得到 HTTP 响应报文并进行解析, 获取到 html 内容并进行渲染; 当然 html 中可能包含很多的标签, 这时候这些标签就会触发第二次请求, 浏览器再根据这些标签信息构造出 HTTP 请求, 重复上面的过程.