Linux网络编程:数据链路层 以太网协议

目录

数据链路层

数据链路层解决的问题

以太网

局域网技术

以太网通信原理

碰撞避免算法

以太网帧格式

MAC帧如何将报头与有效载荷进行分离?

MAC帧如何决定将有效载荷交付给上层的哪一个协议?

理解局域网通信过程

认识MAC地址

对比理解MAC地址和IP地址

认识MTU

MTU对IP协议的影响

MTU对UDP协议的影响

MTU对TCP协议的影响

ARP协议

ARP协议作用

ARP协议的工作流程

为什么要有缓存表?

为什么表项要有过期时间⽽不是⼀直有效?

ARP数据报格式

ARP协议工作流程实例

ARP请求实例

ARP应答实例

进行局域网通信的时候,为什么不直接以广播的方式发送数据?


数据链路层

数据链路层解决的问题

网络层IP提供的是跨网络发送数据的能力,传输层TCP是为数据发送提供可靠性保证的,而链路层解决的则是两台相连主机之间的通信问题。

以太网

局域网技术

不同局域网所采用的通信技术可能是不同的,常见的局域网技术有以下三种:

1.以太网:以太网是一种计算机局域网技术,一种应用最普遍的局域网技术。
2.令牌环网:令牌环网常用于IBM系统中,在这种网络中有一种专门的帧称为“令牌”,在环路上持续地传输来确定一个节点何时可以发送包。
3.无线LAN/WAN:无线局域网是有线网络的补充和扩展,现在已经是计算机网络的一个重要组织部分。

虽然网络中各个局域网所采用的通信技术可能的不同的,但是IP屏蔽了底层网络的差异,对于网络通信双方的IP层及其往上的协议来说,它们并不需要关心底层具体使用的是哪种局域网技术。

数据在发送之前会先进行数据封装,此时链路层会给数据封装上对应的局域网的报头。
如果数据要进行跨网络传输,那么就需要经过路由器转发。
当数据在路由器进行向上交付时,会将该数据对应的局域网报头去掉。
而当路由器该数据转发给下一跳之前,又会给该数据封装上下一跳网络所对应的局域网报头。


也就是说,网络中的路由器会不断去掉数据旧的局域网报头,并添加上新的局域网报头,因此数据在进行跨网络传输时,就算所需跨越的网络采用的是不同的局域网技术,最终也能够正确实现跨越。

以太网通信原理

"以太⽹" 不是⼀种具体的⽹络, ⽽是⼀种技术标准; 既包含了数据链路层的内容, 也包含了⼀些物

理层的内容. 例如: 规定了⽹络拓扑结构, 访问控制⽅式, 传输速率等;

例如以太⽹中的⽹线必须使⽤双绞线(就是路由器上带水晶头的那个); 传输速率有10M, 100M, 1000M等;

以太⽹是当前应⽤最⼴泛的局域⽹技术; 和以太⽹并列的还有令牌环⽹, ⽆线LAN等;

以太网中所有的主机共享一个通信信道,当局域网中的一台主机发出数据后,该局域网中的所有主机都能够收到该数据。

比如当局域网中的主机A想要发送数据给主机B时,其实局域网当中的每一台主机都能收到主机A发出去的数据,只不过最终只有主机B会将主机A发来的数据向上进行交付。
局域网当中的其他主机虽然也收到了主机A发出的数据,但经过识别后发现这个数据不是发送给自己的,于是就会直接将该数据丢弃而不会向上进行交付。

也就是说,在进行局域网通信的时候,局域网当中的所有主机都能够看到局域网中传输的任何数据,只不过每个主机都只关心发送给自己的数据罢了。

扩展:

  • 网络抓包不仅能够抓到发送给自己的报文数据,也能抓取到发给别人的报文数据,实际就是因为在进行网络抓包时,主机将从局域网中收到的所有报文数据都向上交付了而已。
  • 网卡有一种模式叫做混杂模式,被设置为混杂模式的网卡能够接收所有经过它的数据流,而不论其目的地址是否是它。
碰撞避免算法

由于以太网中的所有的主机共享一个通信信道,因此在同一时刻只允许有一台主机发送数据,否则各个主机发送的数据就会相互干扰。站在系统的角度来看,这里各个主机所共享的通信信道就是一种临界资源,这个临界资源同一时刻只允许一台主机使用。

对于这个问题,以太网的做法就是先不限制各个主机发送数据的能力,局域网中的每个主机想发数据的时候直接发就行了,但是只要发送出去的数据与其他主机发送的数据产生了碰撞,那就得执行碰撞避免算法。
所谓的碰撞避免算法就是,当主机发送出去的数据产生碰撞时,该主机需要等待一段时间后再进行数据重发,在主机等待的时候就能够就能够尽可能让局域网当中的数据消散。
以太网通信的原理就像现实生活中开会一样,在开会过程中同一时刻只允许一个人发言,如果两个人突然同时说话,那么双方都会有礼貌的等待别人先说。
也就是说,以太网中主机发送的数据产生碰撞后该主机会执行碰撞避免算法,所以我们说以太网是基于碰撞区和碰撞检测的局域网通信标准。

碰撞避免算法就是主机等待一段时间后重新发送数据,因此以太网底层也有重传机制,只不过以太网的重传机制只是为了保证将数据从局域网中的一台主机发送到另一台主机。

以太网帧格式

源地址和⽬的地址是指⽹卡的硬件地址(也叫MAC地址), ⻓度是48位,是在⽹卡出⼚时固化的;

帧协议类型字段有三种值,分别对应IP、ARP、RARP;

帧末尾是CRC校验码。

MAC帧如何将报头与有效载荷进行分离?

以太网MAC帧的帧头和帧尾都是固定长度的,因此当底层收到一个MAC帧后,直接提取出MAC帧当中固定长度的帧头和帧尾,此时剩下的就是有效载荷了。

MAC帧如何决定将有效载荷交付给上层的哪一个协议?

以太网MAC帧对应的上层协议不止一种,因此在将MAC帧的报头和有效载荷分离后,还需要确定应该将分离出来的有效载荷交付给上层的哪一个协议。

在MAC帧的帧头当中有2个字节的类型字段,因此在分离出报头和有效载荷后,根据该字段将有效载荷交付给对应的上层协议即可。

理解局域网通信过程

假设局域网当中的主机A想要将IP数据报发送给同一局域网当中的主机B,那么主机A封装MAC帧当中的目的地址就是主机B的MAC地址,源地址就是主机A的MAC地址,而帧协议的类型对应就是0800,紧接着就是要发送的IP数据报,帧尾部分对应就是CRC校验。

当主机A将该MAC帧发送到局域网当中后,局域网当中的所有主机都可以收到这个MAC帧,包括主机A自己。

首先发送方会争取发送完整的帧:

  1. 发送与实时监听:主机A开始发送帧,其网卡同时从共享信道上接收信号。

  2. 碰撞检测(核心机制):网卡硬件将接收到的信号它自己正在发送的信号进行实时比对。

    • 一致:说明没有碰撞,继续发送直至完成。

    • 不一致:说明信号在信道中发生干涉(即碰撞)。这是发送方知晓碰撞的瞬间、也是唯一需要的证据。

  3. 立即中止:一旦检测到不一致,网卡立即停止发送当前帧,并发送一个拥塞信号,然后执行碰撞避免算法,等待一段时间后数据重发。这个不完整的帧不会在网络中传播。

完整的帧发送出去后,收到数据的所有主机的第一步,CRC检验,CRC是基于数据内容计算的,从而确保收到的数据内容和发送方发送的数据内容的一致性,避免其他可能因素导致的数据损坏。

CRC的作用(完全不同场景):CRC用于校验已成功完整接收的帧是否在传输中因其他原因(非碰撞,如信号衰减)而出错。对于被碰撞检测机制中止发送产生的碎片,因为其不构成一个合法帧,接收方网卡根本不会对其进行CRC校验。

所有主机第一步——CRC校验:每台主机的网卡都立即对这个帧的完整比特流进行CRC计算。

  • 情况A(数据内容正确):CRC校验通过。所有主机进入下一步。

    • 主机B:检查目的地址,匹配,接收帧并上交。

    • 主机A和其他主机:检查目的地址,不匹配,安静地丢弃帧。

  • 情况B(发生非碰撞因素  导致的 数据损坏):信号畸变,帧的某些比特位翻转了。这会导致所有正在接收的主机(包括主机A自己)计算出的CRC值不匹配

    • 所有主机(包括A、B和其他):在CRC校验这一步就失败了。网卡直接丢弃这个损坏的帧,甚至不会去关心目的地址是谁。

也就是说,碰撞检测是发生在发送端完整正确发送MAC帧之前进行的。

当底层收到一个MAC帧后,首先肯定是没有发生碰撞,发送端的MAC帧正确发送出来了,再会对其进行CRC校验,从而进一步确定数据的一致性,避免其他非碰撞因素导致的数据损坏。CRC匹配正确后再根据MAC帧当中的目的地址来判断该MAC帧是否是发给自己的,如果是发送给自己的则会根据该MAC帧的帧协议类型,将该MAC交付给对应的上层协议进行处理;如果不是发送给自己的就直接丢弃。

认识MAC地址

MAC地址⽤来识别数据链路层中相连的节点;

⻓度为48位, 及6个字节. ⼀般⽤16进制数字加上冒号的形式来表⽰(例如: 08:00:27:03:fb:19)

在⽹卡出⼚时就确定了, 不能修改. mac地址通常是唯⼀的(虚拟机中的mac地址不是真实的mac地

址, 可能会冲突; 也有些⽹卡⽀持⽤⼾配置mac地址).

我们可以通过ifconfig命令来查看我们的MAC地址。

对比理解MAC地址和IP地址

实际数据在路由过程中会存在两套地址,一套是源IP地址和目的IP地址,还有一套是源MAC地址和目的MAC地址。

IP地址描述的是路途总体的起点和终点。
MAC地址描述的是路途上的每一个区间的起点和终点。
比如做公交车时,源IP地址就是我们上车的站点,目的IP地址就是我们最终要下车的站点,而源MAC地址就是公交车上一个已经到达的站点,目的MAC地址就是公交车下一个将要到达的站点。

因此数据在路由过程中,源IP地址和目的IP地址可以理解成是不会变化的,而数据每进行一跳后其源MAC地址和目的MAC地址都会变化。

认识MTU

MTU相当于发快递时对包裹尺⼨的限制. 这个限制是不同的数据链路对应的物理层, 产⽣的限制.

以太⽹帧中的数据⻓度规定最⼩46字节,最⼤1500字节,ARP数据包的⻓度不够46字节,要在后⾯补

填充位;

最⼤值1500称为以太⽹的最⼤传输单元(MTU),不同的⽹络类型有不同的MTU;

如果⼀个数据包从以太⽹路由到拨号链路上,数据包⻓度⼤于拨号链路的MTU了,则需要对数据包

进⾏分⽚(fragmentation);

不同的数据链路层标准的MTU是不同的;

以下的这些影响,都可以借助快递寄包裹来记忆。

MTU对IP协议的影响

具体可以参考上一篇博客:IP分片和组装的具体过程https://blog.csdn.net/dqa__/article/details/155233055?spm=1001.2014.3001.5502

由于数据链路层MTU的限制, 对于较⼤的IP数据包要进⾏分包.

将较⼤的IP包分成多个⼩包, 并给每个⼩包打上标签;

每个⼩包IP协议头的 16位标识(id) 都是相同的;

每个⼩包的IP协议头的3位标志字段中, 第2位置为0, 表⽰允许分⽚, 第3位来表⽰结束标记(当前是

否是最后⼀个⼩包, 是的话置为1, 否则置为0);

到达对端时再将这些⼩包, 会按顺序重组, 拼装到⼀起返回给传输层;

⼀旦这些⼩包中任意⼀个⼩包丢失, 接收端的重组就会失败. 但是IP层不会负责重新传输数据;

MTU对UDP协议的影响

让我们回顾⼀下UDP协议:

⼀旦UDP携带的数据超过1472(1500 - 20(IP⾸部) - 8(UDP⾸部)), 那么就会在⽹络层分成多个IP数据报.

这多个IP数据报有任意⼀个丢失, 都会引起接收端⽹络层重组失败. 那么这就意味着, 如果UDP数据报在⽹络层被分⽚, 整个数据被丢失的概率就⼤ 增加了.

MTU对TCP协议的影响

对于TCP来说,分片也会增加TCP报文丢包的概率,但与UDP不同的是TCP丢包后还需要进行重传,因此TCP应该尽量减少因为分片导致的数据重传。

TCP的⼀个数据报也不能⽆限⼤, 还是受制于MTU. TCP的单个数据报的最⼤消息⻓度, 称为

MSS(Max Segment Size);

TCP在建⽴连接的过程中, 通信双⽅会进⾏MSS协商.

最理想的情况下, MSS的值正好是在IP不会被分⽚处理的最⼤⻓度(这个⻓度仍然是受制于数据链

路层的MTU).

双⽅在发送SYN的时候会在TCP头部写⼊⾃⼰能⽀持的MSS值.

然后双⽅得知对⽅的MSS值之后, 选择较⼩的作为最终MSS.

MSS的值就是在TCP⾸部的40字节变⻓选项中(kind=2);

MSS和MTU的关系如下:

MSS 的作用就是确保“分”这个动作发生在发送端主机的TCP层,而不是发生在中途路由器的IP层。​ 这样就能利用TCP的可靠传输机制,获得极高的效率提升。

ARP协议

地址解析协议(Address Resolution Protocol,ARP)协议,是根据IP地址获取MAC地址的一个TCP/IP协议。

ARP不是⼀个单纯的数据链路层的协议, ⽽是⼀个介于数据链路层和⽹络层之间的协议;

ARP协议作用

在同一个局域网中要给对方发消息,就必须得知道对方的MAC地址,而实际大部分情况下我们只知道对方的IP地址,因此需要通过ARP协议来根据IP地址来获取目标主机的MAC地址。

ARP协议建⽴了主机 IP地址 和 MAC地址 的映射关系.

在⽹络通讯时,源主机的应⽤程序知道⽬的主机的IP地址和端⼝号,却不知道⽬的主机的硬件地址;

数据包⾸先是被⽹卡接收到再去处理上层协议的,如果接收到的数据包的硬件地址与本机不符,则

直接丢弃;

因此在通讯前必须获得⽬的主机的硬件地址;

ARP协议的工作流程

源主机发出ARP请求,询问“IP地址是192.168.0.1的主机的硬件地址是多少”, 并将这个请求⼴播

到本地⽹段(以太⽹帧⾸部的硬件地址填FF:FF:FF:FF:FF:FF表⽰⼴播);

⽬的主机接收到⼴播的ARP请求,发现其中的IP地址与本机相符,则发送⼀个ARP应答数据包给源主机,将⾃⼰的硬件地址填写在应答包中;

每台主机都维护⼀个ARP缓存表,可以⽤arp -a命令查看。缓存表中的表项有过期时间(⼀般为20分

钟),如果20分钟内没有再次使⽤某个表项,则该表项失效,下次还要发ARP请求来获得⽬的主机的硬

件地址

为什么要有缓存表?

为了极致的效率,避免重复且频繁的ARP请求。相当于空间换时间。

为什么表项要有过期时间⽽不是⼀直有效?

为了应对网络变化,保证地址映射的正确性和灵活性。确保IP到MAC的映射是最新、准确的,使通信可靠。

ARP数据报格式

注意到源MAC地址、⽬的MAC地址在以太⽹⾸部和ARP请求中各出现⼀次,对于链路层为以太⽹的情况是多余的,但如果链路层是其它类型的⽹络则有可能是必要的。

硬件类型指链路层⽹络类型,1为以太⽹;

协议类型指要转换的地址类型,0x0800为IP地址;

硬件地址⻓度对于以太⽹地址为6字节;

协议地址⻓度对于和IP地址为4字节;

op字段为1表⽰ARP请求,op字段为2表⽰ARP应答。

从ARP的数据格式也可以看出,ARP是MAC帧协议的上层协议,ARP数据格式中的前3个字段和最后一个字段对应的就是以太网首部,但由于ARP数据包的长度不足46字节,因此ARP数据包在封装成为MAC帧时还需要补上18字节的填充字段。

ARP协议工作流程实例

ARP请求实例

首先路由器D需要先构建ARP请求。

首先,因为路由器D构建的是ARP请求,因此ARP请求当中的op字段设置为1。
ARP请求当中的硬件类型字段设置为1,因为当前使用的是以太网通信。
ARP请求当中的协议类型设置为0800,因为路由器是要根据主机B的IP地址来获取主机B的MAC地址。
ARP请求当中的硬件地址长度和协议地址长度分别设置为6和4,因为MAC地址的长度是48位,IP地址的长度是32位。
ARP请求当中的发送端以太网地址和发送端IP地址,对应就是路由器D的MAC地址和IP地址。
ARP请求当中的目的以太网地址和目的IP地址,对应就是主机B的MAC地址和IP地址,但由于路由器D不知道主机B的MAC地址,因此将目的以太网地址的二进制序列设置为全1,表示在局域网中进行广播。

此时ARP请求构建完成,如下:

ARP请求构建完成后,为了能将ARP请求发送到以太网当中,还需要将ARP数据包向下交付给MAC帧协议,封装成MAC帧。

封装MAC帧报头时,以太网目的地址和以太网源地址,对应分别是主机B和路由器D的MAC地址,但由于路由器D不知道主机B的MAC地址,因此MAC帧报头当中的以太网目的地址的二进制序列也只能设置为全1,表示在局域网中进行广播。
因为这里封装的是一个ARP请求数据包,因此MAC帧当中的帧类型字段设置为0806。
由于ARP请求数据包的长度只有28字节,不足46字节,因此还需要在MAC帧的有效载荷当中补上18字节的填充字段,最后再对MAC帧进行CRC校验即可。

此时ARP请求就被封装成MAC帧了,如下:

MAC帧封装完毕后,路由器D就可以将封装好的MAC帧以广播的方式发送到局域网当中了。

因为这个MAC帧是以广播的方式发出的,因此局域网当中的每台主机收到这个MAC帧后,都会对该MAC帧进行解包。当这些主机识别到MAC帧当中的帧类型字段为0806后,便知道这是一个ARP的请求或应答的数据包,于是会将MAC帧的有效载荷向上交付给ARP层。
当ARP层收到这个数据包后,发现ARP数据包当中的op字段为1,于是判定这是一个ARP请求,然后再提取出ARP数据包当中的目的IP地址字段,虽然局域网当中的所有主机都会将该数据包交给自己的ARP层,但最终只有主机B发现ARP数据包当中的目的IP地址与自己相同,因此只有主机B会对该ARP请求进行应答,而局域网当中的其他主机在识别到ARP数据包当中的目的IP地址与自己不匹配后,就会直接将这个ARP请求报文丢弃。

需要注意的是,局域网当中其他不相干的主机在收到这个ARP请求报文后,不是在MAC帧层丢弃的,而是在ARP层发现该ARP数据包的目的IP与自己的IP不匹配后丢弃的。

ARP应答实例

主机B在应答时首先需要构建ARP应答。

首先,因为主机B构建的是ARP应答,因此ARP应答当中的op字段设置为2。
ARP应答当中的硬件类型、协议类型、硬件地址长度、协议地址长度的值与ARP请求当中设置的值相同。
ARP应答当中的发送端以太网地址和发送端IP地址,对应就是主机B的MAC地址和IP地址。
ARP应答当中的目的以太网地址和目的IP地址,对应就是路由器D的MAC地址和IP地址,因为路由器D发来的ARP请求当中告知了主机B它的MAC地址和IP地址,因此主机B是知道的。

此时ARP应答构建完成,如下:

ARP应答构建完成后,为了能将ARP应答发送到以太网当中,也需要将ARP数据包向下交付给MAC帧协议,封装成MAC帧。

封装MAC帧报头时,以太网目的地址和以太网源地址,对应分别是路由器D和主机B的MAC地址。
因为这里封装的是一个ARP应答数据包,因此MAC帧当中的帧类型字段设置为0806。
由于ARP应答数据包的长度也只有28字节,不足46字节,因此也需要在MAC帧的有效载荷当中补上18字节的填充字段,最后再对MAC帧进行CRC校验。

此时ARP应答就被封装成MAC帧了,如下:

MAC帧封装完毕后,主机B就可以将封装好的MAC帧发送到局域网当中了。

此时局域网当中的每台主机在底层都能收到这个MAC帧,但局域网当中的不相干的主机,在发现该MAC帧对应的以太网目的地址与自己不同后,就会将该MAC帧丢弃,而不会交付给上层ARP层,最终只有路由器D会将解包后MAC帧的有效载荷向上交付给自己的ARP层。
当路由器D的ARP层收到这个数据包后,发现ARP数据包当中的op字段为2,于是判定这是一个ARP应答,然后就会提取出ARP数据包当中的发送端以太网的地址和发送端IP地址,此时路由器D就拿到了主机B的MAC地址。

需要注意的是,局域网当中其他不相干的主机在收到这个ARP应答报文后,直接在MAC帧层就丢弃了,并没有将其交付给自己的ARP层。

进行局域网通信的时候,为什么不直接以广播的方式发送数据?

在进行局域网通信时,就算只知道对方的IP地址,而不知道对方的MAC地址,也可以以广播的方式将数据发送到局域网当中,此时局域网当中的主机也能够在IP层比对目的IP地址与自己是否相符,来判断收到的这个数据是否是发送给自己的。

理论上确实可以这样,但这种方式是不妥的。

对于局域网当中的大多数主机来说,收到的这个报文其实早就应该被丢弃,而现在这个报文却交付到了IP层,我们都知道IP层是属于操作系统管控的,因此这对网络资源和系统资源来说都是一种浪费。
因此在底层MAC帧层就应该判定这个报文是不是发送给当前主机的,而不是当数据向上交付到了IP层再来判断。这里相当于节省了每台主机数据链路层解包到网络层再判断的时间。

此外,如果我要发送100个数据包,如果我有100个主机,直接采用广播相当于我要把数据包发送一万次!而选择ARP协议,就可以开始只发送一个ARP数据包,相当于只发了一百次相比之下几何量级就小了很多了,然后得到目标MAC地址,再进行单播,总共也才发了200个数据包,这样一看就知道哪种方法更节省效率了。

此外,如果无脑使用广播的方式来进行数据的发送,会使得广播和单播的概念变得模糊不清,你明明是想发送数据给局域网当中的一台主机,但你却采用了广播的方式,这显然是不合理的。


此篇完,感谢收看!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_dindong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值