👋 关于作者

你好,这里是一条泥憨鱼 | 专注于 后端开发、AI 前沿技术与计算机基础 。

🏠 个人主页:一条泥憨鱼

通过技术博客记录技术成长,分享学习心得与经验。期待与您共同交流!

📚 精选技术专栏:

❄️后端开发❄️Redis| 黑马点评
❄️从0开始学习计算机网络❄️数据结构与算法
❄️苍穹外卖❄️探秘AI与agent

网络问题里最难查的,往往是“同网段能通、跨网段不通”这类现象,卡点在链路层。

MAC 地址:链路层的“本地门牌号”

IP 地址负责把数据包从一台主机送到另一台主机,但它工作在网络层,是端到端的逻辑地址。真正把数据帧从一个网卡送到相邻网卡的,是 MAC 地址。它是链路层的物理地址,烧在网卡里,48 位,通常写成六组十六进制,比如 `00:1A:2B:3C:4D:5E`。

这 48 位不是随便分配的。前 24 位是 OUI(组织唯一标识符),由 IEEE 分配给厂商;后 24 位由厂商自己编号。理论上这样能保证全球唯一,但实际项目里会遇到“不唯一”的情况:虚拟机可以手动指定 MAC,容器网络会批量生成虚拟 MAC,有些网卡还支持软件改写。所以 MAC 唯一性是个约定,不是物理定律,排查问题时不能假设它一定唯一。

关键在于:MAC 地址只在同一个广播域内有效。数据帧的头部写的是目的 MAC,交换机靠它转发。一旦数据帧要跨越路由器,源和目的 MAC 就会被重写,换成下一跳的地址。换句话说,MAC 是“这一段链路”的地址,不是端到端的地址。

那 IP 怎么变成 MAC?靠 ARP。主机要发数据给同网段的某个 IP,先查 ARP 缓存;没有就广播一个 ARP 请求“谁是这个 IP,请告诉我你的 MAC”,目标主机单播回应。拿到 MAC 后,数据帧才封装得出来。

ARP 缓存是有老化时间的(Linux 默认几分钟),IP 和 MAC 的对应关系变了之后,旧缓存会导致短时间的通信异常。虚拟化环境里做网卡迁移时,这个问题尤其明显。

CSMA/CD:一个已经退役的机制,但值得知道

早期的以太网是共享介质的,所有主机接在同一根总线上,谁发数据大家都知道。问题是,如果两台主机同时发,信号就会叠加、互相干扰,这叫冲突。

CSMA/CD 就是为解决冲突设计的,全称是载波监听多路访问/冲突检测。流程大致是:发送前先监听线路(载波监听),空闲才发;发送过程中继续监听,一旦检测到冲突就立刻停止、发一个干扰信号通知大家,然后各自等待一段随机时间再重试。

这套机制在当年是必要的,但今天基本用不上了。原因很直接:现代以太网用的是交换式全双工链路,每台主机独占一条到交换机的线路,收发走的是不同线对,根本不会冲突。冲突检测失去了存在的前提,CSMA/CD 也就退出了历史舞台。

所以对 CSMA/CD,了解它的存在和大致思路就够了,不必深挖二进制指数退避的具体算法。真正需要记住的是它的退场原因:介质从共享变成独占、从半双工变成全双工,冲突这个前提消失了。

集线器、交换机、路由器:三种转发方式的本质差别

这三种设备经常被混着说,但它们工作在不同的层次,转发依据完全不同。用统一维度对比一下:

| 设备 | 工作层次 | 转发依据 | 冲突域 | 广播域 | 典型场景 |

| 集线器 | 物理层 | 无,纯信号放大 | 全部端口一个 | 一个 | 已淘汰 |

| 交换机 | 链路层 | MAC 地址表 | 每端口一个 | 一个(默认) | 局域网接入 |

| 路由器 | 网络层 | 路由表(IP) | 每端口一个 | 每端口一个 | 网段互联 |

集线器最简单,收到信号就从所有其他端口发出去,它根本不知道帧的内容,所以所有端口在同一个冲突域里,也共享同一个广播域。

交换机进了一步。它维护一张 MAC 地址表,记录“哪个 MAC 在哪个端口”。收到帧时,先看源 MAC,把“源 MAC—入端口”记进表里;再看目的 MAC,查表决定从哪个端口发出去。如果表里没有目的 MAC,就往除入端口外的所有端口泛洪。这个过程会随着通信逐渐收敛:主机 B 回应之后,交换机就学到了 B 在哪个端口,下次不用再泛洪。

路由器则必须拆广播域。它不转发广播帧,每个接口是一个独立的广播域。为什么?因为广播帧如果无限扩散,会占满整个网络的带宽,这就是广播风暴。路由器用 IP 路由表决定往哪转发,同时把广播限制在每个子网内部。

总结差别:集线器看信号,交换机看 MAC,路由器看 IP。层次越高,能做的判断越多,隔离能力也越强。

VLAN:在一台交换机上切出多个“逻辑交换机”

交换机默认把所有端口放在同一个广播域里。设备一多,问题就来了:ARP 广播、DHCP 请求、各种发现协议全在一个域里刷屏,带宽被白白消耗,安全性也没法保证,任何一台机器都能收到别人的广播。

传统做法是用路由器把网络切成多个子网,每个子网一台交换机。但这样成本高、布线死板:部门搬个位置,网线就得重拉。

VLAN 解决的就是这个问题。它在一台物理交换机上划出多个逻辑上独立的交换机,每个 VLAN 是一个独立的广播域。同一 VLAN 内的主机能直接二层通信,不同 VLAN 之间必须经过三层设备。

VLAN 的端口有两种角色。Access 端口连接终端设备,属于某一个 VLAN,收发的帧不带标签,终端根本不知道 VLAN 的存在。Trunk 端口连接交换机或路由器,用来承载多个 VLAN 的流量,帧上必须带标签,否则对端分不清这个帧属于哪个 VLAN。

标签就是 802.1Q 标签。它在原始以太网帧的源 MAC 和类型字段之间插入 4 个字节,其中包含 12 位的 VLAN ID,所以理论上支持 4094 个可用 VLAN(0 和 4095 保留)。

跨交换机转发时,流程是这样的:主机 A 在 VLAN 10 的 Access 端口发帧,交换机给帧打上 VLAN 10 的标签,从 Trunk 口发出;中间交换机通过 Trunk 收到带标签的帧,根据标签知道这是 VLAN 10 的流量,继续从对应的 Trunk 或 Access 口转发;到达目标交换机后,如果出口是 Access 端口,就剥掉标签再发出去。

这里有个必要的提醒:VLAN 不等于网段,但实践中通常一一对应。VLAN 是二层隔离,网段是三层划分,两者是独立的概念。你可以让多个 VLAN 共用一个网段(不推荐,会出问题),也可以让一个 VLAN 里跑多个网段。但工程上为了清晰,一般一个 VLAN 对应一个子网,网关配在三层设备上。

收束:判断转发问题该看哪一层

链路层的这条线理清了,排查问题时就有了顺序。先确认源和目的是不是在同一个广播域:在同一个 VLAN、同一个网段,那就查二层,交换机的 MAC 地址表有没有学到、有没有泛洪、Trunk 有没有放行这个 VLAN。不在同一个广播域,问题就上升到三层,去查路由表、网关配置和防火墙规则。

最容易搞混的一点是 VLAN 和网段的关系。看到“跨 VLAN 不通”,先别急着查路由,确认一下两个 VLAN 的网关是不是都配了、三层设备上有没有对应的 VLAN 接口。VLAN 只管二层隔离,跨 VLAN 通信一定需要三层转发,这个前提漏了,后面怎么查都是白费。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐