交换机是如何偷偷学习的?!它的学习日记大公开!📚
交换机的诞生背景:为什么不用集线器(Hub)了?
要理解交换机,我们先要知道它取代了谁——集线器(Hub)。
-
集线器:一个物理层的“傻瓜”设备。它收到一个数据帧后,不看内容,不看地址,直接把这个信号复制并广播给所有连接的端口。
-
缺点:
-
冲突严重:所有连接在集线器上的设备共享同一个带宽,构成一个巨大的冲突域。任何时候只能有一个设备发送数据,否则就会冲突。设备越多,性能越差。
-
安全隐患:所有设备都能“窃听”到发给其他设备的数据。
-
带宽浪费:发给A的数据,B、C、D也都会收到,占用了它们的链路资源。
-
**交换机(Switch)**的出现就是为了解决这些问题。它是一个数据链路层的“聪明”设备,目标是:将数据帧只发送给需要它的设备,从而隔离冲突域,提高网络效率和安全性。
交换机的核心部件:MAC地址表
交换机的“大脑”是其内部的一张表,我们称之为MAC地址表(MAC Address Table),也叫转发表(Forwarding Table)或CAM表。这张表非常简单,只有两列核心信息:
MAC地址 | 端口号 |
---|---|
00-0A-95-9D-68-16 | 1 |
00-0C-29-1F-E4-7E | 3 |
... | ... |
这张表告诉交换机:“要去往这个MAC地址,请从这个端口出去。”
交换机工作的四大原则
交换机的所有智能行为,都源于以下四个简单却强大的原则。假设一个数据帧到达了交换机的某个端口:
原则一:无条件自学习(Learning)
这是交换机智能的来源。
-
动作:交换机查看该数据帧的源MAC地址。
-
逻辑:它会想:“既然这个MAC地址的设备从这个端口给我发来了数据,那说明它就连接在这个端口上。”
-
建表/更新:交换机将这个“源MAC地址”和“进入端口号”的对应关系写入MAC地址表。
-
如果表中没有这个MAC地址,就新增一条记录。
-
如果表中有这个MAC地址,但对应的端口号变了(比如你把电脑从一个房间换到另一个房间),就更新这条记录。
-
如果记录已存在且无变化,就刷新该条目的老化时间(交换表中的条目会因超时而被删除)。
-
-
关键点:学习只看源地址! 一个设备如果只收数据、从不发送,交换机是永远学不到它的位置的。
原则二:未知则泛洪(Flooding)
这是交换机在“失忆”或“迷路”时的后备方案。
-
动作:在完成学习后,交换机查看该数据帧的目的MAC地址。
-
逻辑:交换机在自己的MAC地址表中查找这个目的MAC地址。
-
找不到怎么办? 交换机不能简单地丢弃这个帧(否则网络就断了)。它会暂时退化成一个“半智能”的集线器。
-
执行:交换机会将这个帧复制并发送给除了该帧进入端口之外的所有其他端口。这个过程就叫泛洪。
-
为什么这么做? 因为网络中总有一个设备是这个帧的目标,泛洪可以保证它一定能收到。更重要的是,当那个目标设备回信时,交换机就能根据回信的帧学习到它的位置(原则一),下次再有发给它的帧,就不用泛洪了。
原则三:知晓则转发(Forwarding)
这是交换机最高效的常规工作模式。
-
动作:交换机查看帧的目的MAC地址,并在MAC地址表中找到了对应的条目。
-
逻辑:表中明确记录着:“要去这个MAC地址,应该从端口X出去。”
-
执行:交换机将该帧仅仅从端口X发送出去。
-
好处:这个数据帧就像被精确制导的导弹,只发往它该去的地方。网络中其他端口连接的设备完全不会被这个通信过程打扰,它们的链路保持空闲,可以进行其他通信。这就隔离了冲突域。
原则四:同源则过滤(Filtering)
这就是你感到困惑的那个关键点,它是“精确转发”的一个特例。
-
动作:交换机查看帧的目的MAC地址,在MAC地址表中找到了对应条目,发现其对应的端口号正好就是这个帧进入的端口号。
-
逻辑:交换机会想:“发送方和接收方都在同一个端口所连接的网段上,我把这个帧再从这个端口发出去毫无意义,因为它们自己就能直接通信。”
-
发生场景:最典型的就是题目中的情况——交换机的某个端口连接了一个集线器,集线器下面又连了多个设备(如X和E)。
-
当X向E发送数据时,集线器会把帧广播给所有连接的设备,所以E已经收到了。
-
交换机也从这个端口收到了同一个帧。
-
此时交换机通过学习知道了X在端口2,通过之前的学习知道了E也在端口2。
-
它发现目的地E和来源X在同一个端口,于是断定这个帧无需自己再帮忙转发了。
-
-
执行:交换机直接丢弃(Discard/Drop)这个帧,不再做任何转发。这个行为就叫过滤。
-
好处:防止了冗余的数据在网络中传播,提高了交换机的处理效率。
总结
用一个流程来概括交换机收到一个帧后的思考过程:
-
看源MAC -> 在MAC地址表中学习/更新
(源MAC, 进入端口)
。 -
看目的MAC -> 在MAC地址表中查找。
-
找不到? -> 泛洪 (向所有其他端口转发)。
-
找到了! -> 得到目标端口。
-
目标端口 == 进入端口? -> 过滤 (丢弃帧)。
-
目标端口 != 进入端口? -> 转发 (向目标端口转发)。
-
-