这一层只管「一段线之内怎么送」,所以它的地址每一跳都会变。 最小帧 64 字节不是浪费,是让冲突检测能成立的代价。
2.4.2 讲的是信号,这一节讲「一段线内怎么组织数据」。 这一节会算填充字节,那个「1 字节要填 49 字节」很反直觉。
一、这一层管一段
三件事,都只在一段线内有效:
| 管什么 | 怎么做 | 范围 |
|---|---|---|
| 成帧 | 加帧头帧尾 | 本段 |
| 寻址 | 用 MAC 地址 | 本广播域 |
| 查错 | 算 CRC | 本段传输 |
第二行那个「本广播域」是关键限制:MAC 地址只在同一段网络里有效,过了路由器就换掉了。 所以它不能当「身份」用——这也是为什么安全认证要靠凭据,不能靠 MAC。 第三行那个 CRC 只校验「这一段传输有没有出错」:它不保证端到端正确, 因为每一跳都会重新算一遍。 端到端的正确性要靠传输层(TCP 的校验和与重传)。 所以「链路层查过错」不等于「数据一定对」。
二、最小帧与填充
以太网规定最小 64 字节,不足的要填充:
| IP 包长度 | 不加填充的帧长 | 需填充 | 实际帧长 |
|---|---|---|---|
| 0 | 14 | 50 | 64 |
| 1 | 15 | 49 | 64 |
| 20 | 34 | 30 | 64 |
| 46 | 60 | 4 | 64 |
| 100 | 114 | 0 | 114 |
第二行那个「1 字节要填 49 字节」最能说明问题: 一个 1 字节的数据,在线上要占 64 字节——放大 64 倍。 这就是「最小帧长」对小包的惩罚。 为什么必须 64 字节,1.9.3 算过:64 字节对应 512 比特、51.2 微秒(10 Mbps), 这个时间要覆盖最远两端的往返传播加 4 个中继器时延。 否则发送方在发完之前收不到冲突信号,会误以为发成功了。 所以「填充」不是浪费,是让冲突检测能成立的代价。 换成全双工交换式以太网之后其实不需要它了——因为全双工没有冲突, 但为了兼容,这个规定一直留着。
三、这一层还会做什么
除了成帧与查错,还有三件常被忽略的事:
| 功能 | 在哪做 | 作用 |
|---|---|---|
| 介质访问控制 | CSMA/CD 或全双工 | 决定谁先发 |
| 流控(PAUSE 帧) | 交换机之间 | 让对端慢点发 |
| VLAN 标记 | 帧头里加 4 字节 | 一段线里划多个广播域 |
第一行在交换式网络里已经退化了:全双工链路上两端各有一对线,不会冲突, 所以 CSMA/CD 实际上不再工作。 但半双工(比如老集线器)还在用它,而且「协商成半双工」是网络变慢的经典原因之一。 第三行那个 VLAN 很实用: 它在以太网头里插 4 个字节,把「一个物理网络」划成多个「逻辑网络」。 所以同一台交换机上的两个口,可以在不同的广播域里。 代价是那 4 个字节会撑大帧长——1500 的 MTU 遇到 VLAN 标记就会变成 1504。
四、动手 Demo:以太网为什么有最小帧长
算「一个 IP 包从 0 字节到 100 字节」时,各要填多少字节。 注意 46 是个分界点:到了 46 就不用填了。
import _netsim as N
for pay in (0, 1, 20, 46, 100):
frame = N.ETH_HDR + pay
pad = max(0, 64 - frame)
print('IP 包 %-4d 帧长 %-4d 填 %-3d 实际 %d'
% (pay, frame, pad, frame + pad))
实跑输出:
--------------------------------------------------------------------
以太网为什么有最小帧长
--------------------------------------------------------------------
**以太网规定最小 64 字节,不足的要填充。**下面算清楚「填充到底填的是什么」。
IP 包长度 不加填充的帧长 需填充 实际帧长
-----------------------------------------------------
0 14 50 64
1 15 49 64
20 34 30 64
46 60 4 64
100 114 0 114
**第二行那个 1 字节的情况要填 49 字节**:**一个 1 字节的数据,在线上要占 64 字节——放大 64 倍。**
**这就是「最小帧长」对小包的惩罚。**
**为什么必须 64 字节,1.9.3 算过**:
**64 字节对应 512 比特、51.2 微秒(10 Mbps),这个时间要覆盖最远两端的往返传播加 4 个中继器时延**
——**否则发送方在发完之前收不到冲突信号,会误以为发成功了。**
**所以「填充」不是浪费,是让冲突检测能成立的代价。**
**换成全双工交换式以太网之后其实不需要它了**,**但为了兼容,这个规定一直留着。**
46 这个分界点怎么来的:64 减 14(以太网头)等于 50,再减 4(帧尾 FCS)等于 46。 所以「载荷 46 字节以上就不需要填充」——这也是为什么以太网的最小 IP 包是 46 字节。 第二行 1 字节要填 49 字节:15 加 49 等于 64。 所以一个 1 字节的 ping 包,在线上占 64 字节。 注意这里算的是「帧长」,没算帧间隔与前导码:线上还要再加 12 字节帧间隔、8 字节前导码, 所以一个 64 字节的最小帧,实际占介质 84 字节的时间。 「64」是帧长,不是「线上占用」。
30 秒实验
- 把 MTU 换成 9000(巨帧),算一下 46 这个分界点会变成多少。
- 算一下:一个 1500 字节的 IP 包,帧长多少?加上帧间隔与前导码占多少?
- 想一下:为什么全双工之后其实不需要最小帧长,却还留着?
常见误区
- 以为最小帧长是为了「对齐」。 它是为了让冲突检测成立:发送方要能在发完之前收到冲突信号。
- 以为 MAC 地址能当身份用。 它只在广播域内有效,过了路由器就换掉了。
- 以为链路层查过错就万事大吉。 CRC 只保证「这一段」没错,端到端正确要靠传输层。
自测三问(点开对答案)
1. 网络接口层管哪三件事?范围多大? —— **成帧、用 MAC 寻址、算 CRC 查错。** 全部只在一段线(一个广播域)内有效。 2. 为什么以太网最小帧是 64 字节? —— **64 字节对应 512 比特、51.2 微秒(10 Mbps)**, 这个时间要覆盖最远两端的往返传播加 4 个中继器时延。 3. 46 这个「不用填充」的分界点怎么来的? —— **64 减 14(以太网头)减 4(帧尾 FCS)等于 46。**所以载荷 46 字节以上就不用填充。下一节往上一层:互联网层,也就是 IP 那一层。
- ☐ (本节完,下一节 2.4.4 互联网层(网络层))