当前位置:首页 > 资讯 > 正文

当你请求www.baidu.com时都发生了什么?

当你请求www.baidu.com时都发生了什么?

目录

一、目录             

二、Hi All             

三、同一个局域网中不同主机的互联             

四、跨网段请求百度的服务器             

五、百度的响应包如何再打回到你的机器?      

二、Hi All

这一次,让 我在 百度告诉你,当你请求www.baidu.com时都发生了什么?以及数据包经历了怎样的过程才被转发到百度的IDC机房的、以及你的电脑又是如何接收到百度的返回的数据包的!

这篇文章会串讲:IPv4、MAC、DNS、交换机、ARP、路由器、路由表、NAT、NAPT、私网、公网、OSI7层网络模型、以及不同机器互联互通原理等计算机网络知识点。

好,我们开始吧!

三、同一个局域网中不同主机的互联

先看个简单的,同一个局域网中的不同主机A、B之间是如何互联交换数据的。如下图:

那,既然是同一个局域网中,说明A、B的ip地址在同一个网段,如上图就假设它们都在  网段。

还得再看下面这张OSI 7层网络模型图。

主机A向主机B发送数据,对主机A来说数据会从最上层的应用层一路往下层传递。比如应用层使用的http协议、传输层使用的TCP协议,那数据在往下层传递的过程中,会根据该层的协议添加上不同的协议头等信息。

图片来自网络

根据OSI7层网络模型的设定,对于接受数据的主机B来说,它会接收到很多数据包!这些数据包会从最下层的物理层依次往上层传递,依次根据每一层的网络协议进行拆包。一直到应用层取出主机A发送给他的数据。

那么问题来了,主机B怎么判断它收到的数据包是否是发送给自己的呢?万一有人发错了呢?

答案是:根据MAC地址,逻辑如下。

 

那对于主机A来说,它想发送给主机B数据包,还不能让主机B把这个数据包扔掉,它只能中规中矩的按以太网网络协议要求封装将要发送出去的数据包,往下传递到数据链路层(这一层传输的数据要求,必须要有目标mac地址,因为数据链路层是基于mac地址做数据传输的)。

那数据包中都需要哪些字段呢?如下:

 

其中的  好说,我们可以直接固定写,或者通过DNS解析域名得到目标ip。

那  怎么获取呢?

这就不得不说  协议了!  其实是一种地址解析协议,它的作用就是:以目标ip为线索,找到目的ip所在机器的mac地址。也就是帮我们找到  地址!大概的过程如下几个step:

简述这个过程:主机A想给主机B发包,那需要知道主机B的mac地址。

  1. 主机A查询本地的arp 高速缓存中是否已经存在  和  地址的映射关系了,如果已存在,那就直接用。

  2. 本地arp高速缓存中不存在  和  地址的映射关系的话那就只能广播arp请求包,同一网段的所有机器都能收到arp请求包。

  3. src ip
    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地址判断。

 

这个例子比较简单,  就是  所以它自己会处理这个数据包。

那数据包处理完之后是需要给主机A一个响应包,那问题又来了,响应包该封装成什么样子呢?对主机B来说响应包也需要  、  、  、 

 

同样的道理,响应包也会按照如下的逻辑被主机A接受,处理。

 

然后再补充一点,我们可以通过下面的命令查看路由转发是否开启:

 

嗯,同一个局域网中的不同主机的通信方式大概就是这样子。下面我们再来看一下跨网段的不同主机的互联原理。

四、跨网段请求百度的服务器

通过上面的描述,如下这张图描述同一个局域网内的不同主机  和  互联的原理大家已经很清楚了。

那不同网段的主机之间是如何互联的呢?

或者说,当你访问:www.baidu.com 时,都发生了什么?你的请求是如何打到百度的服务器机房里面去的?

那,我们先尝试ping一下百度,如下,可以看到百度服务对外暴露的ip地址是 

 

那,再通过  命令看下我的本机ip地址是 

像这种192.168.xx.xx这种局域网机器的ip通常使用dhcp动态分配

我们也可以设置手动设置静态ip

比如可以通过如下命令设置eth0网卡信息

vi /etc/sysconfig/network-scripts/ifcfg-eth0

那,另外我的机器还有运营商分配的公网ip地址: 

有了上面这些信息,于是我们就能画出下面这张图:

然后我们再看一下当我们使用  访问百度时,数据包是如何被一层层转发到百度的IDC机房的,然后我电脑又是如何处理百度的回包的!

对我的机器来说,我想访问百度的服务器,也就是往百度的服务器发数据包的话,那我的电脑得先封装好数据包吧!

那数据包里面起码要包含哪些信息呢?其实在上面的第一节中我们已经说过了,也就是  、  、  、 

对于我的电脑来说:

 

那  目的mac地址是多少呢?这是个问题!

因为我是  网段,百度的服务器在  网段,我们都不在一个网段中!我的机器没法直接获取到百度对外暴露的的mac地址。

那怎么我的机器怎么办呢?

答案是:我的机器会先查看一下自己的路由表,路由表会记录该将这个数据包转发到哪里去。具体可通过  命令可以查看到,如下:

具体的做法就是,拿着  ,分别和路由表中的Genmask做与操作,ip地址 与 子网掩码可以得到该ip地址所在的网段,那得到了  所在的网段之后呢,就拿着这个网段和路由表中的  对比,如果相同的话,就将数据包准发给他。

在我们这个例子中,很明显  跟后三条路由相与得到的结果和route表期望的  都不匹配。

但是  跟第一条路由表中的记录相与,得到的结果肯定符合route预期的  ,毕竟谁与0,结果都是0嘛。(它的Flags为UG,表示它就是,也就是网络的出口)

找到了符合预期的路由后,我的机器就会先将数据包发送给,对应的网卡就是  ,那这也就意味着我们找到了第一个跳目的ethernet地址。于是数据包被封装成下面这样

 

同样的道理,当eth0网卡收到这个数据包后,路由器进行如下的判断。

 

经过上面伪代码的判断,eth0知道了这个包虽然是发给它的,但它并不能继续处理这个数据包,他需要将这个数据包准发给下一跳。

对它现在来说:

 

那  地址怎么获取到呢?其实和上面的流程类似,需要查询路由表。使用  和路由表中的子网掩码相与,得到网段后再与  对比。由于这个路由器上确实没有连接  的网段,所以数据包最终依然会被转发到这个路由器的公网。

经过这一步,数据包流转到路由器的WAN口,再往下走就流入公网啦!

数据包在公网中各个路由节点之间跳转,最终会流转到百度对外暴露的路由器的公网WAN口。

然后数据包会从这个WAN口流入百度内网的IDC机房集群。

你可能会问:那这次请求会打向百度IDC机房中的那台机器呢?

嗯,这就没法再展开了,百度肯定会有他自己的负载均衡机制。我们只需知道这个数据包最终肯定会流转到某一台具体的物理器、或者是某个容器内就好啦!

五、百度的响应包如何再打回到你的机器?

这就要讲到NAT技术了,看下面的这张图:

数据包传输出去的过程中,虽然  始终都是百度对外暴露公网的ip地址,但是  却一直不断的被改变。从一开始的  =>  => 

 

在数据包在被发送到公网之前会被路由器做一次  处理,全称是:  源网络地址转换,它的目的就是将私网ip转换成路由器的公网ip。

当然了,路由器也都会记录下  转换前和转换后的状态。毕竟如果不出意外话,路由器总能接受到百度给他的回包,但他是不能解析处理这个数据包的。(只有请求的发送者  这台机器的应用层才能正确解析出这个响应包)。所以路由器需要根据转发记录将这个包转发给我们起初发送请求的机器(也就是  )。

而这些记录会被路由器记录在它的地址转换表中。

如下:

看上图中绿色的部分,在地址转换表中记录,数据包的原地址从  被转成了  。(这种带端口号的地址转换其实叫  )

那我们继续往下看,假如我们的路由器收到百度的响应包长下面这样:

 

同样的道理,我们家里路由器会有下面伪代码的判断逻辑。

 

最新文章