网络二层与三层数据包转发过程

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

对于搞IT的同行而言,大部分人都不会直接和网络打交道,因此除非从事网络开发,否则对网络内部机制也不会太关心,但是明白网络数据是怎么走的,这对每个IT工程师应该是很重要的基础知识。网络数据包如何在网络上游荡,长久以来也困扰了我很长时间,现在把这部分内容总结分享一下。

  说起网络,大家不约而同会想起大学课本上那个臭名昭著的ISO七层模型,但是ISO模型只是提供了一个参考,并不是具体实现,目前我们使用最多的实现其实是TCP/IP协议族。但是对于TCP/IP,除了表示层和会话层没有体现,其它几层和ISO基本是对应的,从这个角度讲ISO模型还是有参考意义的。

  不扯那么多,我们落地一点:

 

  • 对于物理层而言打交道的基本都是电信号和光信号,例如网卡、光纤、双绞线等都被归到物理层考虑;
  • 对于链路层,数据在离散电/光信号的基础之上,被逻辑划分成一帧一帧(Frame)来管理,这一层是数据交换的主要层面,交换的依据主要是网卡MAC地址,以太网(定义了一种帧格式)、交换机、集线器都划归这一层;
  • 网络层是比链路层更高一级的逻辑层,在这一层主要工作的是路由器,路由器基于IP地址进行跨网链路的计算;
  • 传输层顾名思义是用来控制网络层传输的,因为网络层只是一个“尽力而为”的层,其传输不是完全可靠的,如果将超时重传等可靠性保障机制都交给程序员来做,估计大部分程序员都要疯了,幸好有了传输层提供了TCP和UDP两种机制给我们,才让我们可以高枕无忧的传输数据,而我们在代码里要做的只是打开一个传输层的套接字(即Socket)就可以了;
  • 至于表示层和会话层我们就不多做理解了,这两层基本只是摆设;
  • 应用层是最高层的协议,Web HTTP协议、远程登录SSH协议等都被划归这一层,确切来说这一层已经不属于基础网络了,基本都是软件自定义协议。

 

  理解了网络各层的概念后,我们再回过头来看,在这七层中网络层、链路层、物理层属于低三层,其余属于高四层,从字面上可以看出传输层以下才是真正通过网络传输数据的层面。对于物理层,主要定义的是各种传输介质的信号传输方式,比如时钟频率、电平高低、信道编码等,这一层只是机械的传输,不涉及数据包选路逻辑,链路层(L2层)和网络层(L3层)才是我们要理解的地方。

  首先看L2链路层,这一层以帧(Frame)为单位组织物理信号,每个帧都需要有一个源地址和目的地址,绝大多数情况下使用的都是网卡MAC地址。这一层主要的数据转发设备是集线器和交换机,对于集线器,由于每一个数据帧都会被复制到各个端口,使每个连接主机收到很多跟自己无关的数据帧,这直接导致主机和集线器之间信道冲突剧烈(冲突域属于物理层概念),因此现在基本不用该设备。而交换机则具有MAC地址学习功能,能够向各个端口准确投放数据帧,这样就大大提高了数据传输效率。对于L2层,交换机只能转发一个子网内的数据帧(子网是通过IP地址划分的),如果要将一个数据帧跨网转发,则需要借助于L3层的路径规划功能,这个一会再说。

  现在假设有如下网络拓扑结构,ABCD四台主机属于10.0.0.0子网,网关都指向路由器的10.0.0.1端口,EFGH属于10.0.1.0子网,网关指向路由器的10.0.1.1端口。

   先看同一子网内的通信的情况(A向C发送数据,这种情况下都是通过IP地址指定的),假如所有的主机、交换机和路由器都刚刚加电,内部没有缓存任何MAC映射表和路由表。A在发送之前,发现C和A在同一个子网内,于是A试图先在物理子网内找一下C,但是在同一物理子网内是通过硬件MAC地址来寻址的,而A此时并不知道C的MAC地址,于是A通过ARP广播来试图获取,发出的广播包包括如下类似内容:(注:广播时用的MAC地址是ff:ff:ff:ff:ff:ff)

  交换机1在收到这个ARP广播包后,首先学习到了主机A原来是和1口连接的,然后在缓存中查找C的MAC地址,但是最终没有找到,于是交换机1将这个包从所有端口(连接A的1口除外)发出去,交换机2收到后也会继续广播出去。当主机B和D收到这个广播包之后,发现和自己无关,于是便直接丢弃这个包,不做任何处理;C收到这个广播包后,发现原来是找自己的,于是它发出如下类似格式的回应内容,来告知A自己的身份。

  这个过程对于所有参与的交换机也是个学习的过程,因此交换机1和交换机2也学习到了A和C的位置。至此AC相互找到对方后,便可以在同一物理子网之间直接通过指定MAC地址通信了,他们发送数据帧的类似格式如下:

  下面再来看跨物理网络通信的情况(A向E发送数据),同样假设设备都刚刚加电,缓存为空。A发现E的IP也是同一网段的,于是又开始广播,但是这次BCD都没有回应。我们此时把视线转到路由器1上,当路由器1收到这个ARP广播包后,为了避免广播风暴的产生,路由器1不会继续广播这个ARP包,但是路由器1会把自己的MAC告诉A,回发如下类似格式的内容:

  A在等待超时后,发现当前物理子网内找不到E,但是A已经知道了网关路由器的MAC地址,于是便会将发给E的数据包扔给网关(也就是路由器1的1口),路由器1收到这个包后,发现E的IP在自己内部也没有缓存,于是路由器1也开始了寻找E的过程。相比交换机的子网内“广播找人”,路由器的选路范围更大也更复杂,很多情况下是整个Internet,并且要夸多个运营商,所以在L3层面路由器的路径计算协议较多,包括:RIP、OSPF、IS-IS、BGP、IGRP等协议。路由器之间计算路径时,任何一台路由器都是无法窥探整个网络的,因此每台路由器都只是通过选路算法找到下一跳的最优路径,这些最优路径连接起来便形成了一条完整的路径。换句话说,路由器的转发路径不是一个路由器选择出来的,而是一群路由器共同选择出来的下一跳地址序列。具体的路由选路无法一一讲解,大家感兴趣可以自己调查一下,这里假设路由器1直接找到了路由器2。

  我们继续往下探索,当路由器2接到寻找主机E的广播包后,发现E位于自己的网络中(当然也提前需要一个广播学习的过程才能知道),便向前一跳路由器(即路由器1)反馈自己离主机E最近,最终经过这样一个“A→网关路由器→路由器间选路→找到主机E所在子网”的过程A终于可以与E进行通信了,由于A和E之间经历了多个物理子网,因此需要多次的L2转发才能实现数据包的到达,这个过程中L3层IP包外包帧的MAC地址会不断变换。A→B→A这个过程中,数据帧和IP包的地址经历过程如下(假设A使用的是本机的88端口,B使用的是本机的99端口):

  在这个过程中,数据包在路由器1和2的1<-->4口之间传递时,由于是在一个设备内部,因此可以直接转发,而不用变换帧头,从而提高转发效率。如果A要与其它子网的FGH主机通信,过程基本是一样的,只不过刚开始不会先在当前子网内“广播找人”,而是直接将数据包投递给出口网关。

  本文旨在向大家展示L2交换机和L3路由器在转发网络数据时的一个主要流程,希望能给大家带来帮助。由于3层跨子网计算IP包投送路径协议比较多,先请大家自己参考其它资料。

转载于:https://my.oschina.net/Cubicluo/blog/1509994

你可能感兴趣的:(网络二层与三层数据包转发过程)