1. 解析URL
浏览器先对URL进行解析,从而生成发送给web服务器的信息
2. DNS查询
对URL解析之后可以拿到域名,然后通过DNS查询域名对应的IP地址
DNS的域名用 . 来分割的,越靠右的位置层级越高
比如www.server.com.
.
根域在最顶层,下一层是.com
顶级域,在下面是server.com
域名解析流程也是一级一级进行的。
每次查询前,浏览器会先看自身有没有对这个域名的缓存,如果有,就直接返回,如果没有,就去问操作系统,操作系统也会去看自己的缓存,如果有,就直接返回,如果没有,再去 hosts 文件看,也没有,才会去问「本地 DNS 服务器」。
3. 建立Socket对象
客户端会通过调用Socket库,生成一个Socket对象,然后使用该对象向目标IP地址和端口发送一个连接请求。
4. TCP可靠传输
上面Socket对象发起一个连接请求后,就需要再TCP这里进行连接建立
三次握手建立连接
三次握手目的是保证双方都有发送和接收数据的能力
我们可以在了解一下TCP其他的知识
TCP报文头部格式
- 源端口和目的端口是为了让数据知道从哪里来到哪里去
- 序号是为了 确定数据分割后,能按正确顺序进行重组
- 确认序号 是为了确定数据发出去对方能正确收到。如果没有收到就重新发送,直到收到
- 状态位
SYN
是发起一个连接,ACK
是回复,RST
是重新连接,FIN
是结束连接 - 窗口大小 TCP要做流量控制,通信双方各声明一个窗口,标识自己的处理能力
- 校验和 用于检测数据在传输中是否发生了错误
- 紧急指针 用于指示数据流中的紧急数据,让接收端优先处理
TCP分割数据
HTTP请求消息如果过长,超过了MSS
长度,TCP就需要把HTTP的数据拆解为一块块的数据发送
MTU
:一个网络包的最大长度,以太网中一般为1500
字节。MSS
:除去 IP 和 TCP 头部之后,一个网络包所能容纳的 TCP 数据的最大长度。
TCP报文生成
上面展示的TCP报文头部图中的数据部分,其实就是 HTTP头部+数据
5. IP定位
TCP 模块在执行连接、收发、断开等各阶段操作时,都需要委托 IP 模块将数据封装成网络包发送给通信对象。
IP报文生成
- 源地址IP:客户端输出的IP地址
- 目标地址:通过DNS域名解析得到的Web服务器的IP
6. MAC两点传输
生成了 IP 头部之后,接下来网络包还需要在 IP 头部的前面加上 MAC 头部。
MAC包头格式
发送方MAC地址 和 接收方MAC地址 用于实现 两点之间的传输
在TCP/IP通信中,MAC包头的协议只使用
0800
:IP协议0806
:ARP协议
MAC地址怎么获取?
发送方 的MAC地址获取就比较简单了,存放在网卡生产时的ROM中
那接收方的MAC地址怎么获取?
一般通过ARP
协议找到对方路由器的MAC地址,ARP协议通过广播的形式在以太网中寻找MAC地址
查询后会将MAC地址缓存到ARP协议中,方便以后使用
最终生成网络包
7. 网卡出口
网卡拿到数据报后,会在开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列
- 起始帧分界符是一个用来表示包起始位置的标记
- 末尾的
FCS
(帧校验序列)用来检查包传输过程是否有损坏
最终网卡将包转换为电信号,通过网线发出去
8. 交换机送别
电信号到达网线接口,交换机中的模块会进行接收
通过末尾的FCS进行错误校验,没问题就放在缓冲区中。有问题就丢弃或请求重新发送
交换机端口不具有MAC地址,所以直接将接收到的包放到缓冲区
交换机查询这个包的接收方MAC地址,查看自己的MAC表中是否有该信息,如果有就将包转发走,如果没有就以广播形式寻找
最终数据报通过交换机到达路由器
9. 路由器转发
- 电信号到达网线接口部分,路由器中的模块会将电信号转成数字信号,然后通过包末尾的
FCS
进行错误校验 - 检查 MAC 头部中的接收方 MAC 地址,看看是不是发给自己的包,如果是就放到接收缓冲区中,否则就丢弃这个包
- 完成包接收操作之后,路由器就会去掉包开头的 MAC 头部(MAC头部的作用就是将包送到路由器)
- 路由器会根据 MAC 头部后方的
IP
头部中的内容进行包的转发操作 - 旧的MAC地址删除后,这里也需要重新封装一个新的MAC地址
10. 数据抵达服务器
数据抵达后,会将封装的数据包一层层拆开,然后将客户端需要的东西在返回回去
- 服务器先开MAC头部,判断和自己是否符合
- 开数据包的IP地址是否和自己符合
- 查看TCP的头部,判断序列号是否是自己要的,如果是返回一个ACK;还有端口号, HTTP 的服务器正在监听这个端口号
- 将包发给HTTP进程
- HTTP 进程看到,原来这个请求是要访问一个页面,于是就把这个网页封装在 HTTP 响应报文里
- HTTP 响应报文也需要穿上 TCP、IP、MAC 头部,不过这次是源地址是服务器 IP 地址,目的地址是客户端 IP 地址
- 接着从网卡出去,交由交换机转发到出城的路由器,路由器就把响应数据包发到了下一个路由器,一直跳…
- 到达最后一级路由器,看IP确认是自己的,就将包发给交换机,最后给到路由器
- 客户端最终就收到了数据
11. TCP挥手断开连接
断开连接的时候,不能像建立连接的那样,将ACK+FIN同时返回。
因为断开连接需要处理的问题多,就比如服务端消息没发送完,还没得到ACK;或者是服务端自己的资源要释放等。
所以服务端要经过一个等待,确定可以关闭连接了,重新发送一个FIN给客户端