目录
- 1.DNS
- 2.可靠传输 —— TCP
- 3.远程定位 —— IP
- 4.两点传输 —— MAC
- 5.出口 —— 网卡
- 6.送别者 —— 交换机(可省略)
- 7.出境大门 —— 路由器
- 8.数据包抵达服务器后
- 9.响应过程:
- 带有MAC、IP、TCP头部的完整HTTP报文:
1.DNS
- 客户端首先会发出一个 DNS 请求,问 www.server.com 的 IP 是啥,并发给本地 DNS 服务器(也就是客户端的 TCP/IP 设置中填写的 DNS 服务器地址)。
- 本地域名服务器收到客户端的请求后,如果缓存里的表格能找到 www.server.com,则它直接返回 IP 地址。如果没有,本地 DNS 会去问它的根域名服务器:“老大, 能告诉我 www.server.com 的 IP 地址吗?” 根域名服务器是最高层次的,它不直接用于域名解析,但能指明一条道路。
- 根 DNS 收到来自本地 DNS 的请求后,发现后置是 .com,说:“www.server.com 这个域名归 .com 区域管理”,我给你 .com 顶级域名服务器地址给你,你去问问它吧。”
- 本地 DNS 收到顶级域名服务器的地址后,发起请求问“老二, 你能告诉我 www.server.com 的 IP 地址吗?”
- 顶级域名服务器说:“我给你负责 www.server.com 区域的权威 DNS 服务器的地址,你去问它应该能问到”。
- 本地 DNS 于是转向问权威 DNS 服务器:“老三,www.server.com对应的IP是啥呀?” server.com 的权威 DNS 服务器,它是域名解析结果的原出处。为啥叫权威呢?就是我的域名我做主。
- 权威 DNS 服务器查询后将对应的 IP 地址 X.X.X.X 告诉本地 DNS。
- 本地 DNS 再将 IP 地址返回客户端,客户端和目标建立连接。
通过 DNS 获取到 IP 后,就可以把 HTTP 的传输工作交给操作系统中的协议栈。
应用程序(浏览器)通过调用 Socket 库,来委托协议栈工作。协议栈的上半部分有两块,分别是负责收发数据的 TCP 和 UDP 协议,这两个传输协议会接受应用层的委托执行收发数据的操作。
2.可靠传输 —— TCP
TCP 传输数据之前,要先三次握手建立连接(TCP三次握手过程中的数据包会经过IP层和MAC层的封装和处理,以确保数据能够正确发送到目标服务器,并在网络中进行适当的路由和转发。)这个三次握手的对象是负载均衡器(4层)通过负载均衡算法选择的后台服务器,倘若是7层负载均衡是和负载均衡器建立的三次握手,负载均衡器再与后台的服务器建立三次握手。
三次握手之后如果是https的话,需要进行TSL四次握手
3.远程定位 —— IP
TCP 模块在执行连接、收发、断开等各阶段操作时,都需要委托 IP 模块将数据封装成网络包发送给通信对象。在 IP 协议里面需要有源地址 IP 和 目标地址 IP:
源地址IP,即是客户端输出的 IP 地址;
目标地址,即通过 DNS 域名解析得到的 Web 服务器 IP。
因为 HTTP 是经过 TCP 传输的,所以在 IP 包头的协议号,要填写为 06(十六进制),表示协议为 TCP。加上IP包头,就具备了远程发送的能力了
4.两点传输 —— MAC
生成了 IP 头部之后,接下来网络包还需要在 IP 头部的前面加上 MAC 头部。MAC 头部是以太网使用的头部,它包含了接收方和发送方的 MAC 地址等信息。ARP 协议会在以太网中以广播的形式询问IP地址的MAC地址
5.出口 —— 网卡
网络包只是存放在内存中的一串二进制数字信息,没有办法直接发送给对方。因此,我们需要将数字信息转换为电信号,才能在网线上传输,也就是说,这才是真正的数据发送过程。
负责执行这一操作的是网卡,要控制网卡还需要靠网卡驱动程序。
网卡驱动获取网络包之后,会将其复制到网卡内的缓存区中,接着会在其开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列。
6.送别者 —— 交换机(可省略)
电信号到达网线接口,交换机里的模块进行接收,接下来交换机里的模块将电信号转换为数字信号。将包存入缓冲区,接下来需要查询一下这个包的接收方 MAC 地址是否已经在 MAC 地址表中有记录了。交换机根据 MAC 地址表查找 MAC 地址,然后将信号发送到相应的端口
7.出境大门 —— 路由器
首先,电信号到达网线接口部分,路由器中的模块会将电信号转成数字信号,然后通过包末尾的 FCS 进行错误校验。
如果没问题则检查 MAC 头部中的接收方 MAC 地址,看看是不是发给自己的包,如果是就放到接收缓冲区中,否则就丢弃这个包。(接收方 MAC 地址就是路由器端口的 MAC 地址)
接下来就会进入包的发送操作。
首先,我们需要根据路由表的网关列判断对方的地址。
· 如果网关是一个 IP 地址,则这个IP 地址就是我们要转发到的目标地址,还未抵达终点,还需继续需要路由器转发。
· 如果网关为空,则 IP 头部中的接收方 IP 地址就是要转发到的目标地址,也是就终于找到 IP 包头里的目标地址了,说明已抵达终点。
知道对方的 IP 地址之后,接下来需要通过 ARP 协议根据 IP 地址查询 MAC 地址,并将查询的结果作为接收方 MAC 地址
8.数据包抵达服务器后
服务器会先扒开数据包的 MAC 头部,查看是否和服务器自己的 MAC 地址符合,符合就将包收起来。接着继续扒开数据包的 IP 头,发现 IP 地址符合,根据 IP 头中协议项,知道自己上层是 TCP 协议。于是,扒开 TCP 的头,里面有序列号,需要看一看这个序列包是不是我想要的,如果是就放入缓存中然后返回一个 ACK,如果不是就丢弃。TCP 头部里面还有端口号, HTTP 的服务器正在监听这个端口号。
于是,服务器自然就知道是 HTTP 进程想要这个包,于是就将包发给HTTP 进程。
服务器的 HTTP 进程看到,原来这个请求是要访问一个页面,于是就把这个网页封装在 HTTP 响应报文里。如果是动态页面或者需要查询数据库的数据需要通过fast-cgi(通用网关接口)转发后端的解释器(比如PHP),解释器处理完之后将数据返回,封装到HTTP响应报文中。
9.响应过程:
HTTP 响应报文也需要穿上 TCP、IP、MAC 头部,不过这次是源地址是服务器 IP 地址,目的地址是客户端 IP 地址。历经上面相同的过程最后到达客户端,去除TCP、IP、MAC 头部,剩下HTTP响应报文交给浏览器去渲染页面。
最后如果没有开启长连接,就会向服务器发起 TCP 四次挥手,至此双方的连接就断开了
带有MAC、IP、TCP头部的完整HTTP报文:
图片来源:小林coding