5.9 讲清了交换机"看什么、怎么决定送哪个口"(MAC 地址表、学习、泛洪、过滤),本节讲它"具体怎么把帧搬过去"。拆开看,交换机内部就四件东西:端口与队列(进出都要排队缓存)、交换结构(把帧从入端口搬到出端口的内部通道)、MAC 地址表(查表用硬件、快得离谱)、交换引擎(负责读头、学习、查表、计数)。一次转发的完整旅程是:帧进端口 → 存进队列 → 读帧头(学源 MAC + 校验 FCS)→ 查 MAC 表(命中送 1 个口,未命中或广播泛洪到多个口)→ 经交换结构送到出队列 → 从出端口发出。本节最值钱的一块是三种转发模式:存储转发(读完整个帧 + 校验 FCS 才转,只转好帧、能换速率,今天的主流)、直通式(只读目的 MAC 前 6 字节就转,最快,但坏帧照转)、无碎片(读满前 64 字节再转,折中,能挡冲突残片)。最后一条要记牢:交换机只会"尽力转"——坏帧直接丢、队列满了也丢,它从不重传、也不告诉谁丢了,补上是 TCP 的事(收 3.18)。
5.9 是本节的上半场,本节是下半场。5.9 回答"它凭什么认得路"(MAC 地址表怎么学出来、什么时候泛洪、什么时候过滤),本节回答"它拿什么把帧搬过去"(内部结构、三种转发模式、队列与拥塞、流控)。两节合起来,二层交换机就算讲完了。
- 5.9 创建以太网网络(二层交换机):MAC 地址表、学习 / 泛洪 / 过滤 / 老化、透明转发——本节把那些动作放回机器内部,看它们发生在哪一步
- 5.6 数据的格式(以太网的数据帧格式):FCS 校验与最小帧 64——存储转发要等 FCS、无碎片要读满 64 字节,都是冲着这两个字段去的
- 5.8 控制发送数据的时间(CSMA/CD):本节补上它的两条尾巴——半双工靠"背压"、全双工靠"PAUSE 帧"来控制流量
- 5.7 如何连接(网络拓扑):环路 → 广播风暴 → STP;本节把 STP 实际怎么跑讲一遍(BPDU、根桥、端口状态)
- 5.5 常用的网络接口和线缆是什么(RJ-45接口与UTP线缆):每条链路两头的端口与全双工——本节讲端口这一侧的队列与收发
- 5.3 以太网标准(IEEE802委员会):802.1D/w 生成树、802.3x 流控、802.1Q VLAN、802.3ad 链路聚合——本节的每个"操作"都对应一个标准号
- 4.9 审核公司员工浏览的 Web 网站(代理服务器的用途):公司的上网审计常在交换机上做端口镜像,这是同一类"把流量复制一份出来看"的思路
- 3.18 对应用程序的数据进行可靠传输(TCP):交换机丢帧不通知、不重传——"可靠"是 TCP 事后补的
- 2.3 网络的具体结构(接口(端口)、链路):本节讲的"端口"是交换机自己的口,别和 3.17 的软件端口混
一、先拆开看:交换机内部有哪几件东西
交换机不是"一堆网口插在一起",里面是四件东西在配合:
| 部件 | 干什么 | 一句话 |
|---|---|---|
| 端口 + 队列 | 每个口进出的帧都要先排队缓存 | 因为"进来的速度"和"出去的速度"不总是相等的 |
| 交换结构(Switching Fabric) | 把帧从入端口搬到出端口的内部通道 | 相当于机箱里的"内部高速立交桥" |
| MAC 地址表 | 记"哪个 MAC 在哪个口" | 用专用芯片(ASIC)查,所以又快又不占 CPU |
| 交换引擎 | 读帧头、学习、查表、计数、丢坏帧 | 所有"决定"都在这里做 |
为什么一定要有队列? 想象 4 个千兆口同时往 1 个千兆口送数据:进来的总量是 4 Gbps,出去只有 1 Gbps——差出来的部分只能先存着。存不下就会丢(下一节细说)。
- 共享内存:所有端口共用一块内存,帧写进去再读出来。简单,但受内存带宽限制。
- 共享总线:一条内部总线,端口轮流用。便宜,但有"谁先上总线"的仲裁开销。
- 交叉矩阵(crossbar):任意进出口之间都有一条独立通道,可以同时有好几对在转。现代交换机的主力,也是"几十个万兆口同时线速转发"的物理基础。
二、本节正题:三种转发模式(配图一)
同一台交换机,面对同一个帧,"读到哪一步才肯开始转发"可以有三种选择:
① 存储转发(Store-and-Forward)
把整个帧收完,校验 FCS 通过,才拿去查表转发。
- 好处:坏帧在转发之前就被拦住(FCS 校验不过直接丢);还能做速率转换(万兆口收进来、千兆口发出去,本来就必须先整帧存下来)。
- 代价:延迟最大——延迟 ≈ 帧长 ÷ 速率。1518 字节的帧在 1 Gbps 上,光"等它收完"就要约 12 微秒。
- 今天的主流:交换芯片延迟已经压得很低,这点等待没人计较。
② 直通式(Cut-Through)
只读到目的 MAC(帧头最前面 6 字节),立刻就开始往出端口转——后面的字节边收边转。
- 好处:延迟最低,而且与帧长无关(长帧短帧都是"读 6 字节"的时间)。适合对延迟敏感的场景(金融交易、高性能计算集群)。
- 代价:坏帧照转。等它读到 FCS 发现帧是坏的,这帧早就转到对面去了——坏帧污染了下一段网络。
- 还有速率限制:不能只靠它做"万兆进、千兆出",因为出口根本来不及。
③ 无碎片(Fragment-Free)——折中方案
先读满前 64 字节再转。
- 为什么要 64?因为 64 字节是合法帧的下限(收 5.6)。比 64 字节还短的帧一定是冲突残片(runt)(收 5.8),一眼就能认出来丢掉。
- 所以它能挡掉绝大多数"垃圾帧",又不像存储转发那样要等整帧。是很长一段时间里的性价比之选。
三种模式对照表:
| 存储转发 | 无碎片 | 直通式 | |
|---|---|---|---|
| 读到哪一步转发 | 整个帧 + FCS | 前 64 字节 | 前 6 字节(目的 MAC) |
| 延迟 | 最大(≈ 帧长 ÷ 速率) | 中 | 最小,且与帧长无关 |
| 坏帧 | 拦住 | 挡住残片,挡不住尾部出错 | 照转出去 |
| 能否做速率转换 | 能 | 不能 | 不能 |
| 典型用途 | 通用(今天主流) | 老设备折中 | 低延迟专用场景 |
直通式省下的是"等整帧收完"那点时间,付出的代价是"连坏帧一起转"。 而存储转发多等的这一会儿,买来的是"从它手里出去的帧都验过 CRC"——在今天的芯片速度下,这笔账毫无疑问是划算的。
三、一帧的完整旅程(配图二)
现在把 5.9 的"学习 / 查表 / 泛洪"放回机器内部,完整走一遍:
① 帧进入某个端口 → 先存进「入队列」
不管后面怎么处理,先缓存。这一步是纯物理活,不涉及任何判断。
② 读帧头:学习「源 MAC ↔ 入端口」+ 校验 FCS
- 学习:看到源 MAC,就把"这个号、从这个口进来"记进表(收 5.9)。
- 校验:算一遍 FCS。不过就直接丢——这是"只转好帧"的总闸门。
③ 查目的 MAC:命中 → 1 个口;未命中 / 广播 → 多个口
命中就从对应的那个口送出去;如果查出的口正好是帧进来的口,直接丢(过滤)。查不到、或是广播帧,就从除入端口外所有口各送一份(泛洪)。
④ 经「交换结构」送到出队列 → 从出端口发出
交换结构把帧搬到目标端口的出队列,排队等着从线路发出去。
两个"丢弃点"要记住:
| 丢在哪 | 什么情况 | 后果 |
|---|---|---|
| 第②步:坏帧丢弃 | FCS 校验不过、太短的残片 | 坏帧不会污染下一段网络(存储转发模式下) |
| 第④步:尾丢弃(Tail Drop) | 出队列满了 | 丢包——而且不通知任何人 |
它从不重传,也不告诉谁丢了。所以"交换机丢了一个帧"这件事,只有靠上层察觉:以太网层没有重传机制,是 TCP 发现没收到确认、超时重发(收 3.18)。 这也解释了一个常见困惑:"网络卡了一下,但没报错"——对交换机来说,丢帧不是错误,是正常工作。
四、队列、拥塞与"丢了也不说"
队列不是越大越好。 这话听起来反直觉,但有个名字叫 缓冲膨胀(Bufferbloat):
- 队列太长 → 帧在里面越堆越久 → 延迟从几毫秒涨到几百毫秒
- 而且 TCP 会误判:它以为链路"还很空"(因为没丢包),于是继续加大发送速度,队伍越排越长
- 结果就是"带宽没跑满,但网页要转半天"——卡在延迟上,不是卡在速度上
所以现代交换机会用主动队列管理(如 WRED)在队列快满时提前随机丢一点,逼 TCP 减速——用一点点丢包换整体延迟可控。
再说流控:半双工和全双工用的完全不是一套办法(补 5.8 的账)
| 半双工 | 全双工 | |
|---|---|---|
| 手段 | 背压(backpressure) | PAUSE 帧(IEEE 802.3x) |
| 怎么做 | 故意制造冲突/持续发载波,让对端"听出来线忙" | 发一个专门的暂停帧:"我这边满了,你先停一会儿" |
| 特点 | 间接、粗放,副作用是占着线 | 直接、可协商暂停时长 |
| 为什么半双工不能发 PAUSE 帧 | 因为半双工下不能同时收发,你要发通知的时候正好占着线 |
它是一个以太网帧,类型字段是 0x8808,目的 MAC 是保留组播地址 01:80:C2:00:00:00。
抓到它不奇怪——网卡高级属性里那个"流控制 / Flow Control",开关的就是它(Demo 第一步就会看到)。
五、操作交换机时最常用的四件事
前四节讲的是"交换机自己怎么干",这四件是"人会去动它什么":
① STP / RSTP:防环的自动机制(IEEE 802.1D / 802.1w,收 5.7、5.3)
- 交换机之间每隔约 2 秒互相发一种叫 BPDU 的特殊帧(目的 MAC
01:80:C2:00:00:00)——它不转发给终端,只在交换机之间走。 - 全网先选出根桥(比"桥 ID"= 优先级 + MAC,最小者当选),再让每台交换机算出一条到根桥最短、且无环的路径。
- 落在环上的那段被判为备用,端口进入 Blocking(阻塞)——物理还连着,逻辑上不发帧。主路一断,立刻把备用路放开。
- 端口状态要走一串:Blocking → Listening → Learning → Forwarding。老 STP 收敛要 30~50 秒(这就是当年"断一根线全公司卡半分钟"的来历);RSTP 把它压到秒级。
- 代价要记住:被阻塞的那个口带宽白白闲置——所以才有下面第 ③ 条。
② 端口镜像(SPAN / Mirror)
把一个口(或某个 VLAN)的流量复制一份送到指定的监控口。抓包、入侵检测、上网审计都靠它。
- 注意:镜像会占用带宽和交换芯片的资源,镜像流量大的时候要盯着别把监控口打满。
③ 链路聚合(IEEE 802.3ad / LACP)
把多条线捆成一条逻辑链路:带宽叠加、单线断了不断网。
- 两条硬约束:通常要求同速率、同双工;流量是按"流"(不是按包)分散到各条线上的。
- 所以单条 TCP 连接不会因此变快(它始终走同一条线),能跑满的是"很多条连接同时跑"的总量。这是最常见的误解。
④ VLAN 的两种口:access 与 trunk(IEEE 802.1Q,收 5.3)
- access 口:接终端。进出的帧不带标签——打标签、去标签都由交换机替终端干了,终端毫无感知。
- trunk 口:接交换机、AP。帧带 802.1Q 标签(4 字节,插在源 MAC 之后,收 5.6),一条线能同时跑好几个 VLAN。
- 这就是"交换机是透明设备"的延伸:连 VLAN 这种"改动帧"的活,也只发生在交换机之间,不落到终端头上。
IGMP snooping:不区分的话,组播帧也会被当成广播泛洪(收 3.9)。开了它,交换机就只把组播送给真正要收的那几个口。 风暴控制(storm control):某个口的广播/组播流量超阈值就自动压制,防止一个故障口拖垮全网。 端口安全(port security):限制每个口能学几个 MAC(收 5.9 的 MAC 泛洪攻击防线)。
六、Demo59:把交换机的"内部操作"看一遍
目标:不用买交换机,也能看到流控开关、丢包计数、BPDU、组播加入、VLAN 标签这些只在交换机内部发生的事。
- 看网卡的流控开关(就是 PAUSE 帧):
Get-NetAdapterAdvancedProperty -Name "以太网" | Where-Object {$_.DisplayName -like "*Flow*"} | Format-List DisplayName,DisplayValue→ 正常应为 Enabled。这就是本节说的 802.3x 流控(网卡名字可能叫以太网 2,先在第 2 步确认)。 - 看有没有"被丢掉的帧":
Get-NetAdapterStatistics -Name "以太网" | Format-List→ 关注ReceivedDiscardedPackets/OutboundDiscardedPackets/ReceivedPacketErrors三个计数。 → 有数字不代表坏了——队列满时的尾丢弃是正常工作(本节第四部分)。 - 抓一条 BPDU,看生成树在跑(Wireshark,需接交换机):
过滤器写
stp。 → 你会看到目的 MAC 是01:80:C2:00:00:00的帧,大约每 2 秒一条。 → 展开它,能看到根桥 ID(Root Identifier)——整张网里大家公认的那棵树,根就在那儿。 → 抓不到也正常:家用"傻瓜交换机"和无线网常常不发给你看,或者你的网卡口不是交换口。 - 抓一次组播加入(Wireshark):过滤器写
igmp。 → 打开一个 IPTV / 视频会议 / 在线直播,就能看到"加入组"的报文(收 3.9)。 - 看 VLAN 标签(Wireshark,公司网络里才有):过滤器写
vlan。 → 能看到 802.1Q 标签:Type: 802.1Q (0x8100)+VLAN ID(收 5.3、5.6)。 → 家里抓不到:家用的都是单一 VLAN,交换机不给你看标签。 - 找一条 PAUSE 帧(Wireshark):过滤器写
eth.type == 0x8808。 → 平时很少见;但如果哪台设备在猛灌数据,就能看到"你先停一下"。 - 看交换机管理页上的那几栏:家用/网管交换机管理页面里翻一翻,通常会看到 流量控制 / 生成树(STP)/ 端口镜像 / 链路聚合 / VLAN / IGMP Snooping / 端口限速。 → 这些词就是本节全部内容的开关——能对上号,说明这一节真读进去了。
- 算一次"存储转发多等了多久": 1518 字节 = 12144 比特;在 1 Gbps 上 = 12.1 微秒。 → 这就是存储转发相比直通式"多等"的那点时间,也是"为什么今天没人计较它"的答案。
七、30 秒实验
- 看流控:一条
Get-NetAdapterAdvancedProperty -Name "以太网" | Where-Object {$_.DisplayName -like "*Flow*"}——看到 Enabled,你就找到了 802.3x PAUSE 帧的开关。 - 算一次 12 微秒:1518 字节 ÷ 1 Gbps,心里过一遍——这就是"读完整个帧"的代价,也是直通式想省的东西。
- 找一条 BPDU:Wireshark 过滤
stp,等几秒——看到一个目的地址是 01:80:C2:00:00:00 的帧,就说明生成树正在你身边的交换机上悄悄工作。
八、常见误区
- "直通式一定比存储转发好。" —— 它更快,但会把坏帧转出去,而且不能做速率转换。今天的主流是存储转发。
- "交换机会自动重传丢掉的帧。" —— 不会。它只"尽力转",丢了既不通知也不重传——补上是 TCP 的事(收 3.18)。
- "队列(缓存)越大越好。" —— 太大反而糟糕:缓冲膨胀会让延迟暴涨,还骗得 TCP 继续加速。现代做法是队列快满时主动提前丢一点。
- "交换机丢帧就是网络坏了。" —— 队列满时的尾丢弃是设计内的行为。真正要关心的是"丢得是否持续、是否堆在某个口上"。
- "PAUSE 帧是 TCP 的流控。" —— 两回事。PAUSE 帧是链路层(802.3x)的,只管一跳(邻居之间),且全双工才有;TCP 的流控是端到端的(收 3.18)。
- "半双工也用 PAUSE 帧。" —— 半双工用的是背压(靠制造冲突把线"占住",逼对方等)。你没法一边占着线一边发暂停通知——这就是它只能间接的原因。
- "无碎片模式和存储转发差不多。" —— 差别在只挡住"太短"的残片,挡不住"尾部出错"的坏帧(因为它不看 FCS)。
- "STP 把环路切了,所以带宽也不受影响。" —— 恰恰相反:被阻塞的那个口,带宽是白白闲置的。要"既不闲置又不断环",得靠链路聚合。
- "链路聚合能让我一条下载变快。" —— 通常不能。聚合按"流"分散,单条连接始终走同一条线;快起来的是"很多条连接同时跑"的总量。
- "VLAN 是交换机自动配好的。" —— 要手工配:哪个口是 access(接终端)、哪个口是 trunk(接交换机/AP)。
- "端口镜像不花钱。" —— 镜像要占用带宽和芯片资源,镜像流量大时会拖累性能,也要注意监控口别被打满。
九、动手自测
- 交换机内部有哪四件东西?各自干什么?
- 交换机的队列是干什么用的?为什么非要有?
- 三种转发模式分别"读到哪一步就开始转发"?各自的代价是什么?
- 存储转发相比直通式,多花的时间是多少(举个数)?换来了什么?
- 无碎片模式为什么恰好要读 64 字节?
- 一帧在交换机内部要经过哪几步?两个"丢弃点"分别在哪?
- 什么叫缓冲膨胀?为什么"队列大"反而会让体验变差?
- 半双工和全双工的流控手段有什么不同?为什么半双工不能用 PAUSE 帧?
- STP 靠什么帧互相沟通?"根桥"是怎么选出来的?被阻塞的端口发生了什么?
- 端口镜像、链路聚合、VLAN 的 access/trunk 各解决什么问题?
- 交换结构有哪三种实现?为什么交叉矩阵是现代主力?
答案:
① 端口 + 队列(进出的帧要排队缓存)/交换结构(把帧从入端口搬到出端口的内部通道)/MAC 地址表(记"哪个 MAC 在哪个口",用专用芯片查)/交换引擎(读帧头、学习、查表、校验与计数、丢坏帧)。 ② 因为进来和出去的速度不总是相等(例如 4 个千兆口同时往 1 个千兆口送,进来 4 Gbps、出去只有 1 Gbps),差出来的部分只能先缓存;缓存不下就会丢。 ③ 存储转发:读完整帧并校验 FCS 才转——只转好帧、能换速率,但延迟最大;无碎片:读满前 64 字节就转——能挡冲突残片,折中;直通式:只读前 6 字节(目的 MAC)就转——延迟最小且与帧长无关,但坏帧照转、不能换速率。 ④ 以 1518 字节、1 Gbps 为例:12144 比特 ÷ 1 Gbps ≈ 12 微秒。换来的是"从它手里出去的帧都通过 FCS 校验"(坏帧被拦下),以及不同速率端口之间可以互相转换。 ⑤ 因为 64 字节是合法以太网帧的下限(收 5.6),比 64 字节还短的帧一定是冲突残片(runt)(收 5.8)——读完 64 字节就能确定"这帧至少是完整的",于是既挡住了大多数垃圾帧,又不用等整帧。 ⑥ ①帧进端口 → 存入入队列 → ②读帧头:学习源 MAC ↔ 入端口 + 校验 FCS → ③查目的 MAC(命中送 1 个口;未命中或广播泛洪到多个口)→ ④经交换结构送到出队列 → 从出端口发出。两个丢弃点:第②步的坏帧丢弃(FCS 不过、太短的残片)与第④步的尾丢弃(出队列满)。 ⑦ 缓冲膨胀=队列太长,帧在里面越排越久,延迟从几毫秒涨到几百毫秒;更糟的是 TCP 因为"没看到丢包"而误以为链路空着,继续加速,队伍越排越长。结果是"带宽没跑满、页面却转半天"——卡在延迟而不是速度上。 ⑧ 半双工用背压(故意制造冲突/持续发载波,让对方听出"线忙");全双工用 PAUSE 帧(802.3x)(直接发一个"你先停一会儿"的帧)。半双工不能用 PAUSE 帧,是因为它不能同时收发——你要发通知的时候正好占着线。 ⑨ STP 靠 BPDU(桥协议数据单元,目的 MAC 01:80:C2:00:00:00,约每 2 秒一条,只在交换机之间走)。根桥由"桥 ID = 优先级 + MAC"最小者当选;然后每台交换机算出到根桥最短且无环的路径。落在环上的备用链路,端口进入 Blocking(阻塞)——物理还连着、逻辑上不发帧,主路一断立刻放开(所以那段带宽平时是闲置的)。 ⑩ 端口镜像=把流量复制一份给监控口,用来抓包/审计/入侵检测;链路聚合=多线捆一条,带宽叠加 + 单线故障不断网(按流分散,单条连接不会变快);VLAN 的 access/trunk=access 口接终端、进出不带标签(打/去标签由交换机代劳),trunk 口接交换机或 AP、帧带 802.1Q 标签、一条线跑多个 VLAN。 ⑪ 共享内存(端口共用一块内存,简单但受内存带宽限制)/共享总线(一条内部总线轮流用,便宜但有仲裁开销)/交叉矩阵(任意进出口之间有独立通道,可同时多对转发)。现代主力是交叉矩阵,因为它能支撑"几十个万兆口同时线速转发"。
十、下一步学什么
- ☑ 5.11 二层交换机的操作(Unknown单播数据帧、泛洪) —— 已学完:把 5.9/5.10 里"泛洪"这个动作单独放大——判据的第二维(已知 / 未知)、未知单播帧的三个来源(表没学到 · 表项老化 + 单向流量 · 表满或遭灌表)、泛洪四句机制(除入端口外 · 到广播域边界为止 · 原封不动同一帧 · 顺带把源 MAC 学会)、五条代价、六种把泛洪压下去的手段,以及它和 ARP 的配合(为什么泛洪只发生在第一次)。见 二层交换机的操作(Unknown单播数据帧、泛洪)。
相关笔记
- 二层交换机的操作(Unknown单播数据帧、泛洪) —— 下半场:一帧的旅程第③步"未命中 → 泛洪";本节把它展开成一整节(判据第二维、三个来源、泛洪域 = 广播域、代价与压制手段)
- 创建以太网网络(二层交换机) —— 上半场:MAC 地址表、学习 / 泛洪 / 过滤;本节把那些动作放回机器内部,看它们发生在哪一步
- 控制发送数据的时间(CSMA/CD) —— 半双工与全双工;本节补上两者的流控手段(背压 vs PAUSE 帧)
- 数据的格式(以太网的数据帧格式) —— FCS 校验与最小帧 64;存储转发与无碎片模式都是冲着这两个字段设计的
- 如何连接(网络拓扑) —— 环路 → 广播风暴 → STP;本节讲 STP 实际怎么跑(BPDU、根桥、端口状态)
- 以太网标准(IEEE802委员会) —— 802.1D/w 生成树、802.3x 流控、802.1Q VLAN、802.3ad 链路聚合;本节的每个"操作"都对应一个标准号
- 常用的网络接口和线缆是什么(RJ-45接口与UTP线缆) —— 每条链路两头的端口与全双工;本节讲端口这一侧的队列与收发
- 接口是哪个(MAC地址) —— MAC 是扁平无结构的号;所以交换机只能"建表查表",快而笨
- 负责传输数据的以太网(以太网概要) —— 交换式以太网的三代形态;本节是第三代那台机器的内部剖面
- 审核公司员工浏览的Web网站(代理服务器的用途) —— 上网审计;交换机侧的对应手段是端口镜像
- 对应用程序的数据进行可靠传输(TCP) —— 交换机丢帧不通知也不重传;"可靠"全靠 TCP 事后补
- 接收方是1个还是多个(单播、广播、组播) —— 单播 / 广播 / 组播的三种收件形态;本节补上交换机侧的 IGMP snooping
- 收发数据时的规则(数据打包) —— 打包与校验和;本节讲的是链路层这一遍"校验完再往前走"
- 用于构建网络的设备(网络设备) —— 设备=层的肉身;交换机在链路层,它的一切操作都只看帧