数据链路层(一):帧结构与封装、MAC地址与寻址、以太网帧格式
各位好,欢迎来到数据链路层的第一讲。说实话,很多做嵌入式开发的朋友,对TCP/IP协议栈的熟悉程度远高于数据链路层。但我要说,真正出问题、最难定位的,往往就在这一层。你想想看,物理层把比特流送上去了,数据链路层就得负责把这些比特组织成有意义的“帧”,还得保证它们能准确找到目标设备。今天我们就来把这层的关键概念掰开揉碎了讲清楚。
帧结构与封装:比特流的“集装箱”
物理层传的是原始的比特流,0和1。但光有比特流没用,你得知道从哪里开始读,哪里结束,这包数据是给谁的。数据链路层干的活,就是给这些比特流加上“包装”,这个包装就是帧(Frame)。
我个人习惯把帧想象成一个快递包裹。包裹外面有发件人地址、收件人地址,里面才是真正的货物。帧也一样,它由三大部分组成:
- 头部(Header):包含控制信息,比如目标MAC地址、源MAC地址、上层协议类型等。
- 数据载荷(Payload):上层(网络层)传下来的数据包,比如IP包。
- 尾部(Trailer):通常包含帧校验序列(FCS),用于检测传输过程中是否出错。
核心要点:封装的过程,就是上层数据包“套上”下层的头部和尾部。数据链路层收到网络层的IP包后,在前面加上MAC头部,在后面加上FCS尾部,形成一个完整的帧,然后交给物理层发送。
这里有个容易忽略的点:帧的长度是有上下限的。以太网规定,帧的最小长度是64字节,最大是1518字节(不含前导码)。为什么有最小长度?我在项目中遇到过,如果帧太短,在发送过程中可能还没来得及检测到冲突就发完了,CSMA/CD机制就没法正常工作。嗯,这个后面讲以太网原理时会细说。
MAC地址与寻址:设备的“身份证”
MAC地址,也叫硬件地址或物理地址。它是在设备出厂时烧录在网卡里的,理论上全球唯一。MAC地址长什么样?6个字节,48位,通常用十六进制表示,比如 00:1A:2B:3C:4D:5E。
MAC地址的寻址方式有三种:
- 单播(Unicast):发往单个目标设备。目标MAC地址的第一个字节最低位为0。
- 广播(Broadcast):发往同一广播域内的所有设备。目标MAC地址全为
FF:FF:FF:FF:FF:FF。 - 组播(Multicast):发往一组特定的设备。目标MAC地址的第一个字节最低位为1。
| 寻址类型 | 目标MAC地址特征 | 典型应用场景 |
|---|---|---|
| 单播 | 第一个字节最低位 = 0 | 两台设备直接通信 |
| 广播 | 全F(FF:FF:FF:FF:FF:FF) | ARP请求、DHCP发现 |
| 组播 | 第一个字节最低位 = 1 | 视频会议、流媒体 |
避坑指南:我曾经调试一个网络不通的问题,折腾了半天,最后发现是MAC地址配置错了。设备上电后,网卡会读取MAC地址,如果读出来的是全0或者全F,那通信肯定出问题。所以,在产品量产时,一定要确保MAC地址烧录正确,并且不能重复。
以太网帧格式:Ethernet II vs 802.3
以太网帧格式主要有两种:Ethernet II(也叫DIX以太网)和IEEE 802.3。现在绝大多数网络设备用的都是Ethernet II格式。802.3格式主要用于一些老旧的网络环境或者特定的工业协议中。
我们先看Ethernet II帧格式,这是最常用的:
+----------------+----------------+----------------+----------------+----------------+----------------+
| 前导码 (7B) | 帧起始定界符 | 目标MAC地址 | 源MAC地址 | 类型/长度 | 数据载荷 | 帧校验序列 |
| | (1B) | (6B) | (6B) | (2B) | (46-1500B) | (4B) |
+----------------+----------------+----------------+----------------+----------------+----------------+
关键字段说明:
- 前导码(Preamble):7个字节的10101010...,用于同步时钟。注意,这个字段在物理层处理,数据链路层不关心。
- 帧起始定界符(SFD):1个字节的10101011,表示帧的开始。
- 目标MAC地址:6字节,接收方地址。
- 源MAC地址:6字节,发送方地址。
- 类型/长度字段:在Ethernet II中,这个字段表示上层协议类型,比如0x0800表示IP协议,0x0806表示ARP协议。在802.3中,这个字段表示数据载荷的长度。
- 数据载荷:46到1500字节。如果上层数据不足46字节,需要填充(Padding)到46字节。
- 帧校验序列(FCS):4字节,使用CRC32算法,校验整个帧(从目标MAC地址到数据载荷)的完整性。
IEEE 802.3帧格式与Ethernet II的主要区别在于:
- 802.3的“类型/长度”字段如果值小于等于1500,表示数据长度;如果大于等于1536,表示协议类型。Ethernet II则始终表示协议类型。
- 802.3帧中,如果数据载荷是LLC(逻辑链路控制)数据,则后面还有DSAP、SSAP、Control等字段。
注意:在实际开发中,我们通常用Ethernet II格式。但有些工业以太网协议(如PROFINET)会用到802.3格式。我曾经在做一个工业网关项目时,就因为这个格式不匹配,导致数据解析完全错误。所以,在对接不同设备时,一定要先确认对方用的是哪种帧格式。
下面我用一张图来展示Ethernet II帧的封装过程,以及各层之间的关系:
从这张图可以看得很清楚:数据从应用层一路向下,每一层都会加上自己的头部。到了数据链路层,加上MAC头部和FCS尾部,就变成了一个完整的帧。然后交给物理层,变成比特流发送出去。
接收端的过程正好相反:物理层收到比特流,数据链路层检查FCS,如果校验通过,就剥掉MAC头部和尾部,把中间的IP包交给网络层。
总结一下今天的内容:
- 帧是数据链路层的数据单元,由头部、数据载荷和尾部组成。
- MAC地址是设备的物理地址,用于在局域网内寻址,有单播、广播、组播三种方式。
- 以太网帧格式主流是Ethernet II,通过类型字段标识上层协议;802.3格式主要用于特定场景。
- 帧的封装和解封装过程,是理解整个协议栈通信的基础。