3. 数据链路层基石:MAC地址与帧结构,以太网协议详解,CSMA/CD冲突检测机制
好,我们进入第三讲。说实话,数据链路层是整个网络协议栈里我最喜欢的一层。为什么?因为它离硬件最近,又得跟软件打交道,夹在中间,特别考验设计功底。我当年刚入行时,总觉得这层不就是封装个帧嘛,有啥难的?直到有一次在产线上排查丢包问题,抓了三天包才发现是MAC地址表老化时间配错了……嗯,从那以后我再也不敢小看这层了。
3.1 MAC地址:设备的“身份证”
MAC地址,全称是Media Access Control Address。说白了,就是网卡出厂时烧录的一个唯一标识。48位,6个字节,用十六进制表示,比如 00:1A:2B:3C:4D:5E。
你想想看,IP地址是逻辑地址,可以变;但MAC地址是物理地址,理论上全球唯一。当然,现在虚拟机可以改,但那是软件模拟的,真正的硬件MAC是写死的。
MAC地址结构:
- 前24位(OUI): 组织唯一标识符,由IEEE分配。比如华为的OUI是
00:1A:2B。 - 后24位(NIC): 网络接口控制器编号,由厂商自行分配。
这里有个坑,我必须要说。我曾经遇到一个项目,两台交换机直连,死活不通。查了半天,发现其中一台的MAC地址是广播地址(全F)。嗯,厂商出厂测试时忘了改回来。所以,MAC地址不能全0(未初始化),也不能全F(广播),这是硬规则。
| MAC地址类型 | 第1字节最低位 | 示例 | 说明 |
|---|---|---|---|
| 单播地址 | 0 | 00:1A:2B:3C:4D:5E |
唯一标识一个网卡 |
| 多播地址 | 1 | 01:00:5E:xx:xx:xx |
组播通信使用 |
| 广播地址 | 全1 | FF:FF:FF:FF:FF:FF |
发送给所有设备 |
3.2 以太网帧结构:数据在线上长什么样
数据在网线上跑,不是裸奔的。它得穿件衣服,这件衣服就是“帧”。以太网帧结构,我建议你背下来,因为后面讲VLAN、讲QoS,全得基于这个结构。
标准的以太网帧(DIX 2.0)长这样:
+--------+--------+--------+--------+--------+--------+--------+
| 前导码 | 定界符 | 目的MAC | 源MAC | 类型 | 数据 | FCS |
| 7字节 | 1字节 | 6字节 | 6字节 | 2字节 | 46-1500| 4字节 |
+--------+--------+--------+--------+--------+--------+--------+
我个人习惯把前导码和定界符当成“物理层的事”,真正数据链路层关心的,是从目的MAC到FCS这一段。
小技巧: 抓包时看到前导码和定界符吗?看不到。因为网卡在接收时会自动剥离它们。你看到的第一个字段,就是目的MAC。
这里有个关键点:数据段最小46字节,最大1500字节。为什么是46?因为帧总长度不能小于64字节(否则会被当成冲突碎片丢弃)。64 - 14(头部) - 4(FCS) = 46。如果上层数据不足46字节,必须填充(Padding)。
注意: 我曾经在调试一个物联网项目时,发现设备发送的UDP数据包只有20字节,结果对端收不到。抓包一看,帧长度是60字节(含填充),但接收端网卡认为帧不完整,直接丢弃了。后来发现是网卡驱动对最小帧长度的校验太严格。所以,不要假设所有网卡都按标准来,有些老设备或特殊芯片会有自己的“小脾气”。
3.3 以太网协议:从半双工到全双工
以太网协议,说白了就是一套“谁能在什么时候说话”的规则。早期以太网是半双工的,一根线上只能一个人说话,其他人听着。这就引出了一个问题:如果两个人同时开口,怎么办?
答案是:CSMA/CD(载波监听多点接入/冲突检测)。
我画了一张图,帮你理解CSMA/CD的工作流程:
CSMA/CD的核心逻辑,我总结成四步:
- 先听再说: 发送前先监听信道,没人用才发。
- 边发边听: 发送过程中持续监听,看有没有冲突。
- 冲突就停: 一旦检测到冲突,立即停止发送,并发送一个“阻塞信号”通知所有人。
- 随机等待: 等待一个随机时间后,重新尝试。
这里有个数学问题:随机等待多久?以太网用的是截断二进制指数退避算法。说白了,就是第一次冲突等0~1个时间片,第二次等0~3个,第三次等0~7个……最多到0~1023个。时间片是512比特时间(10Mbps下是51.2μs)。
为什么是512比特时间? 因为以太网最大覆盖范围是2500米,信号来回一趟大约需要51.2μs。这个时间就是“冲突窗口”。如果在这个时间内没检测到冲突,那这次发送就安全了。
3.4 从半双工到全双工:冲突消失了
你可能会问:现在的以太网都是全双工,还有冲突吗?
答案是:全双工模式下,CSMA/CD被禁用了。因为全双工使用独立的发送和接收通道,根本不会冲突。但注意,全双工的前提是点对点连接(交换机到交换机,或交换机到主机)。如果还是用集线器(Hub),那依然是半双工,冲突依然存在。
我建议你记住这个对比:
| 特性 | 半双工(Hub) | 全双工(Switch) |
|---|---|---|
| 通信方式 | 同一时刻只能一方发送 | 双方可同时发送 |
| 冲突检测 | 需要CSMA/CD | 不需要 |
| 最大距离 | 受冲突窗口限制 | 只受信号衰减限制 |
| 利用率 | 低(冲突越多越低) | 接近100% |
嗯,这里要提一句。我见过不少刚入行的工程师,以为全双工就是“双倍带宽”。其实不是。全双工只是让收发可以同时进行,但带宽还是那个带宽。比如100M全双工,发送100M,接收100M,但总吞吐量是200M,这个没错。但如果你说“带宽翻倍了”,严格来说不准确,因为单方向还是100M。
3.5 实战:抓包看以太网帧
光说不练假把式。我建议你打开Wireshark,抓一个包看看。过滤条件设成 eth,然后看帧详情:
Frame 1: 74 bytes on wire (592 bits), 74 bytes captured (592 bits)
Ethernet II, Src: 00:1a:2b:3c:4d:5e, Dst: ff:ff:ff:ff:ff:ff
Destination: Broadcast (ff:ff:ff:ff:ff:ff)
Source: 00:1a:2b:3c:4d:5e
Type: IPv4 (0x0800)
Trailer: 0000000000000000000000000000
[Frame check sequence: 0x12345678 [unverified]]
看到没?Type字段是 0x0800,表示上层是IPv4。如果是 0x0806,那就是ARP。这个字段决定了接收方把数据交给哪个协议栈模块处理。
个人经验: 排查网络问题时,我第一件事就是看MAC地址对不对。有一次客户反馈“网络时通时不通”,我抓包发现源MAC地址在不停变化——原来是一台虚拟机在迁移,MAC地址跟着变了,但交换机的MAC表没及时更新。所以,MAC地址的稳定性,比你想的重要得多。
好了,这一章的内容就到这里。MAC地址、帧结构、CSMA/CD,这三块是数据链路层的基石。你把这些搞透了,后面讲VLAN、讲STP,都会轻松很多。