Linux相关概念和易错知识点(43)(数据链路层、ARP、以太网、交换机)

发布于:2025-09-15 ⋅ 阅读:(18) ⋅ 点赞:(0)

1.从网络层到数据链路层

我们顺着协议栈,经过TCP(UDP),网络层,接下来就应该到链路层了。网络层的报文会向下交付给链路层,链路层会怎么处理呢?我会从它要实现的功能出发,逐个展开。

(1)MAC地址

我们知道IP是网络层的产物,端口号是传输层的产物,他们的本质都是定位一个对象,这样才能正常交付,链路层也有这样的设计。当数据传给链路层之后,链路层之下就是物理层了,直接负责数据传输,所以链路层是数据包装的最底层(非常关键),物理层传输数据的就是经过链路层包装的数据。

数据链路层要解决的第一个问题是:如何知道数据往哪里传?但是IP地址不是已经解决了吗?不同层之间要保证独立,网络层用什么跟数据链路层没关系,这也是为什么一开始就提及IP和端口号,不同层之间要解耦,网络和系统要解耦,这种设计思想我们要体会。

MAC地址48位bit(6字节),是定位不同设备的字段。MAC地址是全球唯一的,在网卡内置。但其实有很多虚拟技术可以虚拟出假的MAC地址,因此MAC地址的唯一性只在局域网内有效。 MAC地址就像在一个班里每个同学的名字,链路层给数据包上一层MAC,就能知道这个数据要交给哪个设备了。

mac地址为48位,即6个字节,一般用16进制数字加上冒号表示,如08:00:27:03:fb:19。

(2)IP地址和MAC地址的区别

虽说我们要保证独立性,但两层都有定位主机的能力,我们也会疑惑IP和MAC有什么区别?

假设我们要从重庆到北京旅游,src是重庆,dst是北京,无论我怎么规划路线,目的地和起源地保持不变,这就是IP。 途中我会有阶段性的目的地,如重庆 -> 武汉,到了武汉之后又有武汉 -> 郑州,阶段性的目标会随着我们的位置变化而变化,这就是MAC。

MAC只负责接下来数据交给哪个设备,而IP则是定位起源地和目的地。 在传输过程中会经过多个设备,链路层的MAC会一直变,而IP保持不变,网络层感受不到链路层干的事,它只觉得数据是从src -> dst,但对于链路层而言,路径却是src -> A -> B -> C -> dst,这也体现出不同层之间的解耦。

在数据链路层包装之后的数据叫做MAC帧(传输层叫做数据段,网络层叫做数据报,链路层叫做MAC帧)。所以各个设备之间真正传输的是MAC帧。

(3)ARP

在知道IP和MAC之间的关系之后,又延伸出来的一个新的问题:IP和MAC之间应当如何转换?这就需要ARP协议了,这是一个位于MAC帧协议(在数据前封装MAC地址等的协议,需要用到MAC地址)之上,位于链路层内的一个协议(在有的模型中会说ARP在网络层,我们了解即可,它的功能是一样的)。它的作用就是解析网络层报文的IP为MAC地址。 但是ARP是如何做到的呢?

首先,发送方的MAC地址ARP是一定知道的,就像每个人一定都知道自己的名字一样。而目的地的MAC地址ARP可以不知道,ARP只需要知道下一跳的地址就行了,就好比从重庆到北京,在重庆的时候只需要研究怎么到武汉就行。

下面举个例子,就能明白ARP的宏观流程了:
老师在讲台上说:我是李老师,哪名学生的学号是10号,告诉我名字。班里的学生都听到了,有人就回答:我是学生小王,学号是10号。

对于设备来说,当它拿着一个IP不知道怎么转为MAC地址时,它就会广播。流程为:我是MAC1,IP1,我要找IP2的MAC,广播后等待回应。如果在同一个局域网内,IP2对应的设备会直接回应自己的MAC;如果不在一个局域网,发送方就会发给路由器,路由器会根据IP路径选择下一跳,返回路由器的MAC(不是IP2的MAC,而是下一跳的MAC地址),循环往复不断轮转,就能实现数据包的跳转。这只是个粗略的流程,我在这里讲解的目的是保证让整个通信的流程跑起来,具体的后面会讲。

目前为止我们知道,网络层封装好数据之后就交给链路层,并且通过ARP得到下一跳的MAC地址,并经由MAC帧协议封装数据形成MAC帧,最后交由物理层,物理层不会再做任何封装,直接发送MAC帧给对应MAC设备。

可以通过arp -a查看ARP缓存。已经ARP过的IP和mac的映射会被保存起来,下次直接交付就不需要广播了,缓存时间是动态的(10 - 30min)。

有个重点需要再次强调,当通信双方在同一局域网内时,ARP可以直接得到对方的mac,传过去就是了;但对于不在一个局域网的情况(IP + 子网掩码判断)它广播时要找的目标IP就是路由器的局域网接口 IP了,ARP得到路由器的mac后直接交给它,此时路由器收到的数据报中的目的IP依然还是最开始要找的,路由器会再进行ARP、传输直到到目的IP手上。从始至终,原IP和目的IP都不会变。

(4)不同层之间的关系

在上述过程中,路由器会收到mac帧,它只会解包走到网络层,读取源IP和目的IP并进行ARP和传输mac帧。在整个过程中,路由器不会去修改网络层里面的原IP和目的IP,要是网络层和数据链路层发现出现丢包,则会直接把剩余数据丢弃,等待传输层触发重传。

简而言之,传输层提供可靠性的策略,也是保证可靠性的地方;网络层提供路径选择的能力;数据链路层帮我们把数据转发到局域网的下一跳,数据链路层和网络层均不会去保证可靠性,TCP/IP 提供传输的方案。逻辑上各个层分别沟通,又相互解耦。

2.以太网

IP是网络层的一个具体实现方案,链路层也有其具体实现方案,如以太网、令牌环网。以太网本身不是一种具体的网络,而是一种技术标准,既包含了数据链路层的内容, 也包含了一些物理层的内容,如规定了网络拓扑结构,访问控制方式,传输速率等,并且以太网中的网线必须使用双绞线,传输速率有 10M,100M,1000M 等。

以太网是当前应用最广泛的局域网技术。 这里有个问题,以太网不是数据链路层里的一个具体方案吗?为什么扯到了局域网?

首先,早期计算机是局域网内通信的,以太网、令牌环网就是其中的解决方案。后来网络诞生后,由于各个实验室都有自己的一套局域网方案(有的在用以太网,有的在用令牌环网),不统一,最后向上搭建了一个网络层。所以从历史上来看,早期的计算机只有数据链路层和物理层,网络层是后来搭建的。所以说网络层之下像以太网、令牌环网这些本身就是以前局域网通信的方案,只不过后来协议栈向上搭建后如今作为数据链路层的实现了。

所以后续以太网的通信方式就可以说是局域网通信的一种方案。mac帧是在局域网内通信的。

(1)以太网的帧格式

根据前面所说,ARP之后我们得到了mac地址,那么以太网的帧格式中就有体现。

这个帧格式是我们学懂数据链路层的关键,其中目的mac和源mac就是ARP得到的,也就是说在数据链路层没有IP地址这个概念,这和网络层是解耦的。

(2)数据分片的原因

我们从帧格式上能注意到数据是46 - 1500字节。但这个问题先不讨论,我们首先要知道这个数据是什么?从协议栈中可知这个数据网络层传过来的,里面包含有网络层的报头。 知道这个时候,我们需要思考为什么数据大小有限制?

①碰撞域

以太网(局域网)的通信就像在上课一样,老师说的话全班都能听到,叫一声小王所有人都能收到数据,但只要意识到不是叫的自己,这份数据也就无效了。

主机A(源地址macA)发送数据到主机B(目的地址macB)。在局域网内通信时,每台主机都有一个协议栈,每个主机收到数据后解包得到目的mac,不匹配的就丢弃。匹配的话主机会根据帧格式中的“类型”处理,如果是0800,就向上交给IP层继续解包处理。

在一个班里,一堆人同时讲话,你能听清谁说的什么吗?同样,两个主机同时发数据就可能出现数据碰撞问题。如果数据干扰了,那谁也没办法正常接收。 所以为了避免局域网中的数据碰撞问题,理论上我们需要保证同一时刻有尽量少的主机在使用局域网资源,这样碰撞的概率才足够低。

怎么保证?首先我们假设两个主机同时发数据,并发生了碰撞,被碰撞的主机怎么办?碰撞后,两台主机都要休眠一段时间,并且触发重发机制。链路层的重发是尽量保证没有碰撞,即碰撞避免。 注意碰撞避免只是在链路层内保证一定的可靠性,它并不会管端到端的可靠性,那是传输层干的事。

从另一个角度来理解,整个局域网叫做一个碰撞域。因此以太网其实就是一个临界资源,碰撞避免就是在保护临界资源。同理,令牌环网的规则是谁拿令牌谁说话,牌子流转于每台主机之间,这就是互斥锁,它本质上也是保护临界资源。

②MTU

了解了碰撞域之后,我们需要思考,在一个碰撞域中主机是越多越好还是越少越好?肯定越少越好,主机越多容易发生碰撞,所以一个局域网内主机多了就需要交换机,交换机可以隔绝碰撞域。

还有个问题,单台主机中发送数据,数据帧的长度越长越好还是越短越好?越长的话,主机占用以太网时间过多,更容易和其他数据碰撞,且触发碰撞避免后重传代价大,所以不易太长;但也不能太少,这样的话发送密度大,发送过于频繁同样会对以太网造成一定的拥堵。

那么到底数据帧的长度怎样才合适呢?这就引出了以太网的最大传输单元(MTU,IP层传下来的数据的最大值),即1500 字节。 但注意实际数据帧大小大于1500字节,MTU限制的是IP传下来的数据,还得加上以太网包装的字段。

这就是帧格式中限制IP层传下来的数据必须满足[46,1500]的原因,只要我们从碰撞域这个概念出发去理解,MTU就绝对不只是一个空洞的概念,它是有自己的合理性的。

③网络层和传输层的处理

如果链路层接收到的数据不在[46, 1500]内,就会被直接丢弃,所以这就要求网络层和传输层得适应规则了,即分片操作(仅在网络层进行,链路层不参与分片,它只负责约束,传输层也不会分片,它向下交付完整数据,接收完整数据)。

对于UDP来说,一旦UDP携带的数据超过1472字节(1500 - 20(IP层首部) - 8(UDP首部)),那么它就会在IP层分片,传输到目标主机后再进行重组,将重组好的完整数据交给传输层。如果分组有任意一个发生了丢失,即标志着数据在IP重组失败,剩下的数据也不会想上交付,全部都被丢弃。 这对传输层来讲就是丢包了,UDP需要应用层处理。

对于TCP来说,传输层携带的数据必须在1460字节(1500 - 20(IP层首部)- 20(TCP首部)),这个1460字节也称为MSS,即最大段尺寸。这个值小于UDP的分片阈值,所以只要控制数据在MSS以内的话,IP层就一定不会分片了。

TCP双方三次握手SYN时还会交换MSS,选择较小的MSS值为最终值。MSS协商不是必须的,TCP报头的选项中可以有这种协商。

如果用户只想传输1字节,经过TCP包装后为41字节 < 46字节,交给链路层后会被填充为46字节,后续解包时链路层再丢弃这些填充字段交给网络层。

(3)类型

①正常交付

在以太网中,发送出去的数据帧是有类型的,常规情况下就是0x0800,接收方接收到mac帧之后,看到0800之后就会解包,并将数据交给IP层进一步处理。

②ARP请求

这是最关键的一点,上面我们简单说了ARP是链路层 / 网络层中的一个协议,负责将IP转为mac地址,标准来讲ARP是网络层的,但其实现却实际依赖链路层以太网帧协议的“类型”。 下面是最详细的流程,了解之后我们才算彻底理解ARP:

首先,IP层包装了数据交给了链路层,交付之后链路层才会知道目标IP是什么,但链路层的通信是靠mac,于是链路层在收到IP的数据之后会先读取IP报头获取源IP和目标IP;之后,链路层会根据读取到的信息包装一个类型为0806的数据帧,随后在局域网内广播出去。

这就是以太网拿到IP报文后发起的ARP请求格式,最外层的数据帧没什么不同,但类型字段为0806,并且按照全F为目的地址发送,这样局域网内每个收到mac帧的主机都会认为自己是目标主机,并且根据类型也知道这是个ARP请求。

发起请求的ARP字段中仅有发送端IP、发送端mac、目标IP,没有目标mac(填充,无意义)接收方拆开看到自己是目标IP后会重新发起一个ARP应答,格式和上面的一模一样,就是op改为2,即应答模式。同时里面发起方、接收方的IP和mac都知道,直接点对点单播而非广播。发起ARP请求的主机收到应答后根据类型和op读取里面的IP和mac,这就实现了一次ARP。

每一次ARP之后,其ARP的IP和mac的映射会被缓存起来,但仅有一个约20min的有效时间。这是考虑到目标主机下线,配置变更,安全保障等因素而设计的。

ARP请求/应答字段的设计是通用的,令牌环网等其它局域网也是这么设计的。所以说可以看到发送端mac地址在上述图中重复了一次,第一次是以太网帧格式里面,第二次在ARP字段中,出现两次并不冗余,ARP不能依赖某个具体的链路层方案,应该是通用且解耦的。

③总结

不同类型说明了以太网中数据的类型,以及接收方怎么处理数据,应该将数据交给哪个协议去处理,0800交给IP,0806交给ARP,8035交给RARP。

通过类型我们也彻底理解了ARP的过程,先接收IP数据报,根据报头IP信息发起0806的请求mac帧,收到应答后再发出0800的mac帧。如果发现目标IP不在当前局域网内时ARP的目标IP就是路由器了,路由器应答后直接发给路由器。整个过程中会发现网络层的报头目标IP和源IP不变(暂不考虑NAT)。路由器收到后进行路径选择、转发,直到到达目标主机处。

(4)CRC

CRC是负责对发送的mac帧查错误的,如果发送前会根据帧的内容计算得到一个CRC的值,目标收到之后会再算一遍,如果CRC不匹配,这个mac帧就直接丢弃了。相应的IP层重组分片也会失败,最终就等着TCP或应用层判断重传了。

3.交换机和集线器

(1)交换机的作用

碰撞域是以太网中会遇到的问题,其他局域网如令牌环网、无线LAN等遇到的情况并不完全相同。 所以如果要黑掉一个以太网,其思路就是往以太网里不断发送垃圾数据,去碰撞别人的数据包,只需要直接从网络层绕过链路层发送,规避碰撞检测即可。

正常情况下,主机越多网络越慢,这符合我们的常识,这是因为我们的主机频繁发生了碰撞检测和碰撞避免,缓解的方法之一就是引入交换机。

交换机的核心的作用就是划分碰撞域。我们买了一个交换机接入网络之后,刚开始交换机不处理数据,但要做扩散,即转发数据。交换机在转发数据时会进行学习,例如macA从接口1发送过来了一个数据,交换机会进行记录;又有一个macB也从接口1回应了一个数据,交换机也会记录。注意交换机只会记录发送过来的数据,发送出去都是扩散式的,从各个接口发送出去,不会记录。 某个时候,macA要给macB发送数据了,macA和macB都在接口1这边,交换机就不会从其它接口扩散了;或者交换机已知macC在接口2这边,macB给macC发消息时交换机就只会像接口2这边扩散了。

因此,交换机能够划分碰撞域,不会扩散碰撞域。

(2)理解交换机

但是还有个问题,交换机这个概念应该怎么插入到我们现有的知识体系中?

其实上述过程仅适用于有线局域网的情况。

每个联网的主机都和交换机的一个接口相连,一般来说交换机的一个接口只会连接一个设备。如果我们想要让交换机的一个接口连接多个设备或者说交换机的接口数量不够了,我们就可以级联交换机。总之我们现在需要认识到,每个设备都是有线的且都连向交换机,包括路由器也会有接口连向交换机(我们家庭买的路由器自带一个交换机)。

在一个局域网内,macA想向macB发送消息,过去我们说的都是ARP得到目的mac,然后发过去,但其实这个过程不完善,我们一直忽略了有线这个条件,这也是我们将交换机融入已有知识体系的难点所在。实际上,A在链路层准备好ARP请求的mac帧之后,在物理层会通过线将数据从交换机的一个接口传到交换机里面,同时交换机通过mac帧格式缓存源mac和接口。之后交换机通过mac帧里面的目的mac,先查找交换机的缓存,如果没有找到目的mac对应接口的缓存,就向所有其它接口转发mac帧,由于每个设备都连向交换机,所以所有设备都会收到mac帧。匹配上的就会回应,回应途中也是经过交换机传数据,交换机也同样会缓存传来的源mac及其端口。

当macD想要发数据给macF时,macD将mac帧通过线传给交换机,这个时候如果交换机在缓存中找到macF及其对应的接口后,就会直接把mac帧转发过去,而不会给每个接口都转发。有可能转发过去后就找到了macF,但也有可能是进入了另一个交换机,这个交换机会继续在其缓存里面找macF,找到了就通过对应接口发过去,找不到就向所有其它接口都发送mac帧。

为什么说交换机能够划分碰撞域,不会扩散碰撞域呢?当macA发数据给macB时回先发给交换机,交换机如果找到了缓存会直接通过找到的接口转发mac帧,该交换机的其它接口连接的设备都不会收到mac帧,就减少了碰撞的风险。 同时,如果macA和macB都在同一个接口,那么macA的帧传入交换机后不会有任何转发,因为B一定不在这边,那么交换机的其它接口连接的设备都不会受到影响。 因此我们可说交换机能够划分碰撞域,不会扩散碰撞域。

这个数据传输方式适用于所有情况,局域网和跨网段都是如此,因为路由器也是一台主机,它也会有一条线连接至交换机的一个接口。当A想要给B发消息时,根据IP + 子网掩码发现不在同一局域网,这时候它的下一跳就是路由器。这个时候A也是把mac帧交给交换机,让交换机按照上述规则扩散转发给路由器。

(3)集线器

这个设备现在用的比较少了,但在这里能帮助我们理解交换机。

macA和macB本应连接到交换机的两个接口,但是我想让它们只连接到一个接口,且我不想大费周章级联一个交换机,这时集线器就是个好选择。A和B两根线连着集线器,集线器引出一根总线连接至交换机的一个接口。这时A和B发的消息在交换机看来都来自同一个接口。

macA想给macB发消息时,macA会发给集线器,打算由集线器交给交换机,集线器交给交换机的同时,也会向连接集线器的所有设备广播,这样B就没有通过交换机转发。而交换机看到macA和macB在同一个接口的情况下,也不会有任何转发操作。

因此我们就可以理解,当macA和macB对应接口一致时,交换机就算不做任何转发,数据也能传到B那里,靠的还是集线器的特点。 要是集线器换成交换机,那就按照前面的规则走一遍也行。

从集线器这里的特点也能看出,集线器不像交换机那样能隔绝碰撞域,一个主机发消息,其它连接着集线器的主机全部都会收到消息,因此同一时刻只能有一份数据在集线器里传输,这就意味着集线器的带宽会被平分,所以它才会逐渐被交换机替代。