1. 目的
把「键入网址,到网页显示,期间发生了什么?」这个问题所涉及到的协议、网络设备都要掌握,比如 HTTP、DNS、TCP、UDP、IP、ARP、MAC 等等
2. 背景
当一台位于局域网(LAN)中的计算机想要访问互联网上的资源时,会涉及到不同的网络协议和网络设备
此处尚缺一个网络拓扑图
https://zhuanlanjia.com/post/225
3. DNS解析
在真实网络传输过程中,其实压根就不会用到域名这个东西。点对点传输是基于IP地址进行交互的。所以,网络传输的第一步就是做域名解析,通过域名将IP地址换回来,然后再进行后续操作。
https://www.cnblogs.com/qingdaofu/p/7399670.html
3.1. 域名系统
3.2. 域名解析过程
获得IP地址后,用户主机中的浏览器可以通过Web服务器的IP地址对其进行访问了
递归查询和迭代查询
DNS请求为什么用UDP?能不能使用TCP
使用UDP 优势是不需要经过 TCP 三次握手的过程,从而大大提高了响应速度。但也有缺点,容易被地方运营商劫持, 给你推送垃圾广告。为了避免被劫持,很多大厂都用了HttpDNS
4. 数据包转发
相关工具nexttrace或者Tracert命令,可以帮助理解数据包的转发过程
怎么理解数据包转发呢?这里简单举个例子,比如说你给远方的朋友写信,信写好后,先放到信封里。然后找到邮局,把信封投递出去。邮局收到你的信封后,根据信封上的地址,帮你送到朋友那里。朋友收到你的信封以后,拆开信封,看到了你写的祝福,然后进行回信,回信的过程跟你寄信过程一样。这样一来一回,就是一个完整的请求-响应。整个过程中:
信的内容就是原始的消息体
信封就好比是消息体的组装,组装的结果就是数据报文
邮局就是网关,他接收我们的信件,并统一进行分发
信封上写的地址就是DNS请求出来的IP地址
邮局送信过程就是IP数据包寻路过程,也就是所说的路由
在讲数据包转发之前我们先聊聊IP地址,因为数据包转发是基于IP地址的,IP地址分为私有地址
和公有地址
两种。 私有地址主要用于在局域网中进行分配,在 Internet上是无效的。这样可以很好地隔离局域网和 Internet,也能节省IP资源,而公有地址
是全球唯一的
私有地址
A类、B类、C类
IP以及子网掩码
子网掩码该如何理解呢?简单来说就是为了隔离广播域,掩码越长广播域越小
假如说某个学校一年级总人数是100人,如果不分班,老师讲话,所有的学生都能听到,如果分了10个班,每个班只有10人,那老师讲话只有10个人可以听到。通过分班(子网掩码),可以很好隔离广播域。另外要注意的一点是,广播域越大,交换机设备的压力也会越大,因为同一个数据包需要复制多份发出去,所以有了子网掩码就能很好的规避这个问题
当一台机器有了IP以及子网掩码以后,是不是就能直接发送数据报文了呢?No,No,No这里还有一个关键点没讲,那就是MAC地址,数据包在从网卡发送出去之前一定要知道下一跳的MAC地址,这里的下一跳包含2种场景:
1 . 下一跳是网关
2 . 下一跳是相同子网下的IP
如果你访问的是一个公网地址,那么数据包的下一跳会丢给网关,让网关接着转发。 如果说下一跳是同子网下的IP,那么它不需要经过网关,这时它会通过ARP广播查找同子网下的MAC,拿到目标IP+MAC后,数据包就可以正常转发了
对于第一个场景,当网关拿到去公网的数据包该如何处理呢?它的处理方式,查找本地路由表,找到下一跳出口,然后将数据包转发出去
5. 数据包封装之网络协议
右边是客户端,可以理解成我们浏览器,左边是服务器。中间涉及到TCP、IP、ARP网络协议。协议栈分为几个部分,分别承担不同的工作。上下关系是有一定的规则的,上面的部分会向下面的部分委托工作,下面的部分收到委托的工作并执行
应用程序(浏览器)HTTP请求通过调用 Socket 库,来委托协议栈工作。协议栈的上半部分有两块,分别是负责收发数据的 TCP 和 UDP 协议,它们俩会接受应用层的委托执行收发数据的操作。
协议栈的下面一半是用 IP 协议控制网络包收发操作,在互联网上传数据时,数据会被切分成一块块的网络包,而将网络包发送给对方的操作就是由 IP 负责的。
此外 IP 中还包括 ICMP 协议和 ARP 协议。
- ICMP 用于告知网络包传送过程中产生的错误以及各种控制信息。
- ARP 用于根据 IP 地址查询相应的以太网 MAC 地址。
IP 下面的网卡驱动程序负责控制网卡硬件,而最下面的网卡则负责完成实际的收发操作,也就是对网线中的信号执行发送和接收操作
如果 HTTP 请求消息比较长,超过了 MSS 的长度,这时 TCP 就需要把 HTTP 的数据拆解成一块块的数据发送,而不是一次性发送所有数据。
- MTU :一个网络包的最大长度,以太网中一般为 1500 字节。
- MSS :除去 IP 和 TCP 头部之后,一个网络包所能容纳的 TCP 数据的最大长度。
数据会被以 MSS 的长度为单位进行拆分,拆分出来的每一块数据都会被放进单独的网络包中。也就是在每个被拆分的数据加上 TCP 头信息,然后交给 IP 模块来发送数据。
简单看看TCP报文格式
源端口号和目标端口号是必不可少的,如果没有这两个端口号,数据就不知道应该发给哪个应用。接下来是包的序号,这个是为了解决包乱序的问题。在 HTTP 传输数据之前,首先需要 TCP 建立连接,TCP 连接的建立,通常称为三次握手
下面简单讲讲IP协议:TCP 模块在执行连接、收发、断开等各阶段操作时,都需要委托 IP 模块将数据封装成网络包发送给通信对象。我们先看看 IP 报文头部的格式
在 IP 协议里面最重要的是源地址 IP 和目标地址 IP :
- 源地址 IP ,即是客户端输出的 IP 地址;
- 目标地址 IP ,即通过 DNS 域名解析得到的 Web 服务器 IP
日常所说的五元组
数据就是:源IP、源端口、目的IP、目的端口、协议 所组成
6. 流量接入层
客户端请求流量送到VIP以后,首先要经过的是4层负载均衡,4层负载均衡它的特点是性能好,但缺点是它只处理TCP、UDP、ICMP4层相关的协议,如果要处理HTTP 7层协议,那就需要用到Nginx7层代理,最终将数据包转发到服务器上。
数据包抵达服务器后,服务器会先扒开数据包的 MAC 头部,查看是否和服务器自己的 MAC 地址符合,符合就将包收起来。
接着继续扒开数据包的 IP 头,发现 IP 地址符合,根据 IP 头中协议项,知道自己上层是 TCP 协议。
于是,扒开 TCP 的头,里面有序列号,需要看一看这个序列包是不是我想要的,如果是就放入缓存中然后返回一个 ACK ,如果不是就丢弃。TCP 头部里面还有端口号,HTTP 的服务器正在监听这个端口号。
于是,服务器自然就知道是 HTTP 进程想要这个包,于是就将包发给 HTTP 进程。
服务器的 HTTP 进程看到,原来这个请求是要访问一个页面,于是就把这个网页封装在 HTTP 响应报文里。
HTTP 响应报文也需要穿上 TCP 、IP 、MAC 头部,不过这次源地址是服务器 IP 地址,目的地址是客户端 IP 地址。
穿好头部衣服后,从网卡出去,交由交换机转发到出城的路由器,路由器就把响应数据包发到了下一个路由器,就这样跳啊跳。
最后跳到了客户端的城门把手的路由器,路由器扒开 IP 头部发现是要找城内的人,于是把包发给了城内的交换机,再由交换机转发到客户端。
客户端收到了服务器的响应数据包后,同样也非常的高兴,客户能拆快递了!
于是,客户端开始扒皮,把收到的数据包的皮扒剩 HTTP 响应报文后,交给浏览器去渲染页面,一份特别的数据包快递,就这样显示出来了!
最后,客户端要离开了,向服务器发起了 TCP 四次挥手,至此双方的连接就断开了。