📚 第二章 TCP/IP基础知识
📄 一句话概括

这一层只管「一段线之内怎么送」,所以它的地址每一跳都会变。 最小帧 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 秒实验

  1. 把 MTU 换成 9000(巨帧),算一下 46 这个分界点会变成多少。
  2. 算一下:一个 1500 字节的 IP 包,帧长多少?加上帧间隔与前导码占多少?
  3. 想一下:为什么全双工之后其实不需要最小帧长,却还留着?

常见误区

  1. 以为最小帧长是为了「对齐」。 它是为了让冲突检测成立:发送方要能在发完之前收到冲突信号。
  2. 以为 MAC 地址能当身份用。 它只在广播域内有效,过了路由器就换掉了。
  3. 以为链路层查过错就万事大吉。 CRC 只保证「这一段」没错,端到端正确要靠传输层。
自测三问(点开对答案) 1. 网络接口层管哪三件事?范围多大? —— **成帧、用 MAC 寻址、算 CRC 查错。** 全部只在一段线(一个广播域)内有效。 2. 为什么以太网最小帧是 64 字节? —— **64 字节对应 512 比特、51.2 微秒(10 Mbps)**, 这个时间要覆盖最远两端的往返传播加 4 个中继器时延。 3. 46 这个「不用填充」的分界点怎么来的? —— **64 减 14(以太网头)减 4(帧尾 FCS)等于 46。**所以载荷 46 字节以上就不用填充。

下一节往上一层:互联网层,也就是 IP 那一层。

相关笔记