这一次!我在百度告诉你,当你请求百度时都发生了什么...
一、Hi All#
这一次,我在 IDC 机房告诉你,当你请求 www.baidu.com 时都发生了什么?以及数据包经历了怎样的过程才被转发到百度的 IDC 机房的、以及你的电脑又是如何接收到百度的返回的数据包的!
这篇文章会串讲:IPv4、MAC、DNS、交换机、ARP、路由器、路由表、NAT、NAPT、私网、公网、OSI7 层网络模型、以及不同机器互联互通原理等计算机网络知识点。
好,我们开始吧!
二、同一个局域网中不同主机的互联#
先看个简单的,同一个局域网中的不同主机 A、B 之间是如何互联交换数据的。如下图:
那,既然是同一个局域网中,说明 A、B 的 ip 地址在同一个网段,如上图就假设它们都在192.168.1.0
网段。
还得再看下面这张 OSI 7 层网络模型图。
主机 A 向主机 B 发送数据,对主机 A 来说数据会从最上层的应用层一路往下层传递。比如应用层使用的 http 协议、传输层使用的 TCP 协议,那数据在往下层传递的过程中,会根据该层的协议添加上不同的协议头等信息。
根据 OSI7 层网络模型的设定,对于接受数据的主机 B 来说,它会接收到很多数据包!这些数据包会从最下层的物理层依次往上层传递,依次根据每一层的网络协议进行拆包。一直到应用层取出主机 A 发送给他的数据。
那么问题来了,主机 B 怎么判断它收到的数据包是否是发送给自己的呢?万一有人发错了呢?
答案是:根据 MAC 地址,逻辑如下。
那对于主机 A 来说,它想发送给主机 B 数据包,还不能让主机 B 把这个数据包扔掉,它只能中规中矩的按以太网网络协议要求封装将要发送出去的数据包,往下传递到数据链路层(这一层传输的数据要求,必须要有目标 mac 地址,因为他是基于 mac 地址做数据传输的)。
那数据包中都需要哪些字段呢?如下:
其中的dst ip
好说,我们可以直接固定写,或者通过 DNS 解析域名得到目标 ip。
那dst mac
怎么获取呢?
这就不得不说ARP
协议了! ARP
其实是一种地址解析协议,它的作用就是:以目标 ip 为线索,找到目的 ip 所在机器的 mac 地址。也就是帮我们找到dst mac
地址!大概的过程如下几个 step:
简述这个过程:主机 A 想给主机 B 发包,那需要知道主机 B 的 mac 地址。
主机 A 查询本地的 arp 高速缓存中是否已经存在
dst ip
和dst mac
地址的映射关系了,如果已存在,那就直接用。本地 arp 高速缓存中不存在
dst ip
和dst mac
地址的映射关系的话那就只能广播 arp 请求包,同一网段的所有机器都能收到 arp 请求包。收到 arp 请求包的机器会对比 arp 包中的
src ip
是否是自己的 ip,如果不是则直接丢弃该 arp 包。如果是的话就将自己的 mac 地址写到 arp 响应包中。并且它会把请求包中src ip
和src mac
的映射关系存储在自己的本地。
补充:
交换机本身也有学习能力,他会记录 mac 地址和交换机端口的映射关系。比如:mac=a,端口为 1。
那当它接收到数据包,并发现 mac=a 时,它会直接将数据扔向端口 1。
当然,也可以看下维基百科中列举的同局域网中两台 computer 互联的简单例子:
再看下 linux 操作系统中的 arp 命令:
嗯,在 arp 协议的帮助下,主机 A 顺利拿到了主机 B 的 mac 地址。于是数据包从网络层流转到数据链路层时已经被封装成了下面的样子:
网络层基于 ip 地址做数据做转发
数据链路基于 mac 地址做数据转发
根据 OIS7 层网络模型,我们都知道数据包经过物理层发送到机器 B,机器 B 接收到数据包后,再将数据包向上流转,拆包。流转到主机 B 的数据链路层。
那主机 B 是如何判断这个在数据链路层的包是否是发给自己的呢?答案前面说了,根据目的 mac 地址判断。
这个例子比较简单,dst ip
就是主机B的本机ip
所以它自己会处理这个数据包。
那数据包处理完之后是需要给主机 A 一个响应包,那问题又来了,响应包该封装成什么样子呢? 对主机 B 来说响应包也需要src ip
、src mac
、dst ip
、dst mac
同样的道理,响应包也会按照如下的逻辑被主机 A 接受,处理。
然后再补充一点,我们可以通过下面的命令查看路由转发是否开启:
嗯,同一个局域网中的不同主机的通信方式大概就是这样子。下面我们再来看一下跨网段的不同主机的互联原理。
三、跨网段不同主机的互联#
通过上面的描述,如下这张图描述同一个局域网内的不同主机192.168.1.3
和192.168.1.2
互联的原理大家已经很清楚了。
那不同网段的主机之间是如何互联的呢?
或者说,当你访问:www.baidu.com 时,都发生了什么?你的请求是如何打到百度的服务器机房里面去的?
那,我们先尝试 ping 一下百度,如下,可以看到百度服务对外暴露的 ip 地址是220.181.38.148
那,再通过ifconfig
命令看下我的本机 ip 地址是192.168.0.64
像这种 192.168.xx.xx 这种局域网机器的 ip 通常使用 dhcp 动态分配
我们也可以设置手动设置静态 ip
那,另外我的机器还有运营商分配的公网 ip 地址:121.36.30.75
有了上面这些信息,于是我们就能画出下面这张图:
然后我们再看一下当我们使用192.168.0.64
访问百度时,数据包是如何被一层层转发到百度的 IDC 机房的,然后我电脑又是如何处理百度的回包的!
对我的机器来说,我想访问百度的服务器,也就是往百度的服务器发数据包的话,那我的电脑得先封装好数据包吧!
那数据包里面起码要包含哪些信息呢?其实在上面的第一节中我们已经说过了,也就是src ip
、src mac
、dst ip
、dst mac
对于我的电脑来说:
那dst mac
目的 mac 地址是多少呢?这是个问题!
因为我是192.168.0.X
网段,百度的服务器在220.181.38.X
网段,我们都不在一个网段中!我的机器没法直接获取到百度对外暴露的网关的 mac 地址。
那怎么我的机器怎么办呢?
答案是:我的机器会先查看一下自己的路由表,路由表会记录该将这个数据包转发到哪里去。具体可通过route -n
命令可以查看到,如下:
具体的做法就是,拿着dst ip 220.181.38.251
,分别和路由表中的 Genmask 做与操作,ip 地址 与 子网掩码可以得到该 ip 地址所在的网段,那得到了dst ip
所在的网段之后呢,就拿着这个网段和路由表中的Destination
对比,如果相同的话,就将数据包准发给他。
在我们这个例子中,很明显dst ip 220.181.38.251
跟后三条路由相与得到的结果和 route 表期望的Destination
都不匹配。
但是dst ip 220.181.38.251
跟第一条路由表中的记录想与,得到的结果肯定符合 route 预期的Destination
,毕竟谁与 0,结果都是 0 嘛。(它的 Flags 为 UG,表示它就是网关,也就是网络的出口)
找到了符合预期的路由后,我的机器就会先将数据包发送给网关,对应的网卡就是eth0
,那这也就意味着我们找到了第一个跳目的 ethernet 地址。于是数据包被封装成下面这样
同样的道理,当 eth0 网卡收到这个数据包后,路由器进行如下的判断。
经过上面伪代码的判断,eth0 知道了这个包虽然是发给它的,但它并不能继续处理这个数据包,他需要将这个数据包准发给下一跳。
对它现在来说:
那dst mac
地址怎么获取到呢? 其实和上面的流程类似,需要查询路由表。使用src ip
和路由表中的子网掩码相与,得到网段后再与Desitantion
对比。由于这个路由器上确实没有连接220.180.38.xxx
的网段,所以数据包最终依然会被转发到这个路由器的公网网关。
经过这一步,数据包流转到路由器的 WAN 口,再往下走就流入公网啦!
数据包在公网中各个路由节点之间跳转,最终会流转到百度对外暴露的网关路由器的公网 WAN 口。
然后数据包会从这个 WAN 口流入百度内网的 IDC 机房集群。
你可能会问:那这次请求会打向百度 IDC 机房中的那台机器呢?
嗯,这就没法再展开了,百度肯定会有他自己的负载均衡机制。我们只需知道这个数据包最终肯定会流转到某一台具体的物理器、或者是某个容器内就好啦!
四、百度的响应包如何再打回到你的机器?#
这就要讲到 NAT 技术了,看下面的这张图:
数据包传输出去的过程中,虽然dst ip
始终都是百度对外暴露公网网关的 ip 地址,但是src ip
却一直不断的被改变。从一开始的192.168.0.64
=>192.168.0.1
=> 121.36.30.75
在数据包在被发送到公网之前会被路由器做一次SNAT
处理,全称是:source network address translator
源网络地址转换,它的目的就是将私网 ip 转换成路由器的公网 ip。
当然了,路由器也都会记录下SNAT
转换前和转换后的状态。毕竟如果不出意外话,路由器总能接受到百度给他的回包,但他是不能解析处理这个数据包的。(只有请求的发送者192.168.0.64
这台机器的应用层才能正确解析出这个响应包)。所以路由器需要根据转发记录将这个包转发给我们起初发送请求的机器(也就是192.168.0.64
)。
而路由器将这些记录 记录地址转换表中。
如下:
看上图中绿色的部分,在地址转换表中记录,数据包的原地址从192.168.0.64:1234
被转成了121.36.30.75:1234
。(这种带端口号的地址转换其实叫NAPT
)
那我们继续往下看,假如我们的路由器收到百度的响应包长下面这样:
同样的道理,我们家里路由器会有下面伪代码的判断逻辑。
这样的话,我们的发送请求的机器就接收到百度的响应包了,响应数据再一路往 OIS7 层网络模型的上层传递,最后到应用层根据 http 协议解析出响应报文,经过浏览器渲染 html 报文,于是下面的网页就展现在了我们面前!
来源:https://www.cnblogs.com/ZhuChangwu/p/15183365.html
评论