3. 物理层与数据链路层:以太网帧结构、MAC地址、CSMA/CD协议、交换机工作原理
各位同学,今天我们聊聊网络最底层的两兄弟——物理层和数据链路层。说实话,很多搞了几年开发的朋友,对这两层的理解还停留在“网线插上去就能通”的阶段。但实际工作中,恰恰是这些底层细节,决定了你的网络到底稳不稳。
我个人习惯把这两层放在一起讲,因为它们在以太网里配合得太紧密了。物理层负责把比特流变成电信号或光信号扔到线上去,数据链路层则负责把这些比特组织成有意义的“帧”,还要解决谁先发谁后发的问题。
3.1 以太网帧结构——数据在线上到底长什么样?
你想想看,两台电脑之间传数据,总不能光着屁股把比特流扔出去吧?总得有个信封,告诉接收方“这是谁发的”、“发给谁”、“里面装的是什么类型的数据”。这个信封,就是以太网帧。
标准的以太网帧(IEEE 802.3)长这样:
| 字段 | 长度(字节) | 说明 |
|---|---|---|
| 前导码 | 7 | 用于同步时钟,101010...的交替模式 |
| 帧起始定界符(SFD) | 1 | 最后两位是11,表示帧正式开始 |
| 目标MAC地址 | 6 | 接收方的物理地址 |
| 源MAC地址 | 6 | 发送方的物理地址 |
| 长度/类型 | 2 | 小于1500表示长度,大于1536表示上层协议类型 |
| 数据载荷 | 46~1500 | 上层传下来的IP数据包,不够46字节要填充 |
| 帧校验序列(FCS) | 4 | CRC32校验,检查传输过程中有没有出错 |
这里有个关键点:数据载荷最少46字节,最多1500字节。为什么是46?因为整个帧(从目标MAC到FCS)最短要有64字节,减去18字节的头部和尾部,剩下46。如果上层数据不够,网卡会自动填充0。
我曾经在项目里遇到过一个问题:某台设备发出来的包,Wireshark 里看到数据部分全是0,但应用层却说数据丢了。排查了半天,发现是上层协议栈传下来的数据只有20字节,网卡填充了26个0,但接收方没正确处理填充字段,直接把填充数据当成有效载荷了。嗯,这就是没按规范来。
3.2 MAC地址——网络设备的身份证
MAC地址,全称是Media Access Control Address。说白了,就是网卡出厂时烧录的一个唯一标识。48位,通常写成6组十六进制数,比如 00:1A:2B:3C:4D:5E。
前24位是厂商代码(OUI),由IEEE分配。后24位是厂商自己分配的序列号。理论上全球唯一,但实际中……嗯,你懂的,有些小厂会乱来。
MAC地址有三种类型:
- 单播地址: 第一个字节的最低位为0,表示发给单个设备。
- 多播地址: 第一个字节的最低位为1,表示发给一组设备。
- 广播地址: 全F,即
FF:FF:FF:FF:FF:FF,表示发给所有设备。
你想想看,当一台设备收到一个帧时,它会先看目标MAC是不是自己。如果是,就收下;如果不是,就扔掉。但如果是广播地址,所有设备都得收下——这就是广播风暴的根源。
3.3 CSMA/CD协议——老式以太网的“交通规则”
在早期的以太网里,所有设备都连在同一根同轴电缆上(总线型拓扑)。大家共用一条线,谁想发数据谁就发。但问题来了:如果两台设备同时发,信号就会在线上撞在一起,谁也收不到。
CSMA/CD 就是解决这个问题的。全称是 Carrier Sense Multiple Access with Collision Detection,翻译过来就是“载波监听多路访问/碰撞检测”。
它的工作流程,我总结成四步:
- 先听再说: 发送前先监听线路。如果线路空闲,就发;如果忙,就等。
- 边发边听: 发送过程中继续监听。如果检测到碰撞(信号电平异常),立即停止发送。
- 发个通知: 发送一个32位的“阻塞信号”,告诉所有设备“刚才撞了,大家注意”。
- 随机等待: 等待一个随机时间(退避算法),然后重新尝试。
我记得刚入行时,师傅让我排查一个网络时延大的问题。我测了半天,发现只要流量一大,丢包率就飙升。后来发现,那台老交换机还在用半双工模式,CSMA/CD 频繁触发退避,导致有效吞吐量直线下降。换成全双工后,问题立刻解决。
3.4 交换机工作原理——从“共享”到“交换”
交换机是数据链路层的核心设备。它不像集线器(Hub)那样无脑转发,而是根据MAC地址表来智能转发。
交换机的三个核心功能:
- MAC地址学习: 每收到一个帧,就把源MAC地址和入端口记录下来,更新MAC地址表。
- 帧转发/过滤: 查MAC地址表,如果找到目标MAC对应的端口,就只往那个端口转发;如果没找到,就广播到所有端口(除了入端口)。
- 环路避免: 通过生成树协议(STP)防止网络环路。
下面这张图,是我自己画的交换机工作流程,你看一眼就明白了:
交换机的MAC地址表是动态学习的。默认是空的,每收到一个帧就学一条。如果一段时间没收到某个源MAC的帧,表项就会老化删除(默认老化时间300秒)。
交换机有三种转发模式:
| 模式 | 延迟 | 错误检测 | 适用场景 |
|---|---|---|---|
| 直通转发 | 低(几微秒) | 无 | 内部高速网络,链路质量好 |
| 存储转发 | 高(整个帧收完) | 完整CRC校验 | 广域网,链路质量差 |
| 无碎片转发 | 中等(收前64字节) | 过滤碎片帧 | 混合场景 |
我个人习惯在生产环境里用存储转发模式。虽然延迟稍微大一点,但能过滤掉错误帧,避免坏帧在网络里扩散。你想想看,如果让一个CRC校验失败的帧一路转发下去,接收方应用层拿到错误数据,那后果可比多等几微秒严重多了。