就像快递员分拣包裹 数据链路层如何用MAC地址和帧把网络数据包精准投递到目标设备
先把场景搭起来——你网购了一件东西,快递单上写了发货人、收货人,还有快递公司、分拣中心、运输路线这些信息。包裹到了每个中转站,分拣员不看里面装的啥,只看单子上的地址,判断往哪个方向送。
数据在网络里传输,道理几乎一模一样。
你发送的那条消息,经历了几层”打包”
当你在浏览器输入一个网址,或者微信发出消息时,数据并不是一口气传过去的。它要经过OSI模型的分层处理,每层都有自己的职责。
网络层(IP层)负责的是”从北京到上海”这种跨城市的宏观路由——告诉数据包目标机器的IP地址,以及怎么穿越整个互联网找到方向。
但到了最后一环,数据包需要从一个设备物理传到同一个局域网内的另一个设备,这时候数据链路层就出场了。它负责的是”从你家门口到你邻居门口”这段最后一公里的路。
你想象一下:IP地址像是城市的门牌号,而MAC地址像是每台设备的”出厂身份证号”,刻在网卡芯片里,全球唯一。
MAC地址:每台设备的”身份证”
MAC地址由48位二进制数组成,通常写成六组十六进制,比如:
AA:BB:CC:DD:EE:FF
前三个字节是厂商识别码(OUI),后三个字节是设备序列号。比如 00:1A:2B 开头可能是一台华为的设备,D8:9E:F3 可能是一台iPhone。
这是出厂时就烧录好的,理论上全球唯一,不会重复。你可以把它理解为:
- IP地址是动态分配的,你可以换WiFi、换网络,IP会变
- MAC地址是硬件绑定的,只要网卡不换,它永远在那里
帧:把数据包装进”快递盒”
数据链路层收到网络层下来的数据包后,不会直接扔出去。它会先做一个动作——封装成帧。
一个标准的以太网帧长这样:
| 前导码 | 目标MAC | 源MAC | 类型 | 数据(IP数据包) | 帧校验序列 |
| 8字节 | 6字节 | 6字节 | 2字节 | 46-1500字节 | 4字节 |
- 目标MAC:这帧要送给谁
- 源MAC:谁发出的
- 类型:里面装的是IPv4数据包还是IPv6数据包
- 数据:真正的payload,也就是网络层交下来的IP包
- FCS:帧校验序列,用来检测传输过程中有没有出错
你可以理解为:IP数据包是信件内容,而帧是装信的快递袋,上面贴着收件人和寄件人的地址,还有防拆封的检测码。
局域网里怎么找设备?ARP协议是”查号台”
这是最关键的一步。
假设你的电脑IP是 192.168.1.10,你要发给 192.168.1.20,你知道目标IP,但数据链路层不认识IP,它只认MAC地址。
怎么办?这时候ARP(地址解析协议)就派上用场了。
你的电脑会向整个局域网广播一条消息:
“谁是 192.168.1.20?请告诉我你的MAC地址!”
所有设备都收到了这条广播,但只有 192.168.1.20 这台设备会回应:
“是我!我的MAC地址是
00:11:22:33:44:55。”
你的电脑把这个映射关系缓存起来,以后再发给这个IP就直接用MAC地址封装帧了。
这个ARP缓存表,你可以自己在电脑上看:
在终端输入:
# Windows
arp -a
# macOS / Linux
arp -a
你会看到类似这样的输出:
接口: 192.168.1.10 --- 0x12
Internet 地址 物理地址 类型
192.168.1.1 aa-bb-cc-dd-ee-ff 动态
192.168.1.20 00-11-22-33-44-55 动态
224.0.0.1 01-00-5e-00-00-01 静态
每一行就是一台设备的IP和MAC的对应关系。
交换机:智能的分拣员
在没有交换机以前的老网络里,用的是集线器。集线器是个纯粹的”广播设备”——你发一个信号,所有人都能收到,效率极低,还容易撞车。
现代局域网用的是交换机,它聪明得多。
交换机内部维护着一张MAC地址表,记录了:
端口 1 → AA:BB:CC:11:22:33(你的电脑)
端口 2 → 00:11:22:44:55:66(你的路由器)
端口 3 → DD:EE:FF:AA:BB:CC(你的NAS)
当一帧进入交换机时,它会做两件事:
- 学习:看帧的源MAC地址,记录是从哪个端口进来的
- 转发/过滤:看帧的目标MAC地址,只从对应的端口发出去,而不是广播给所有人
这意味着——你的电脑发给NAS的数据帧,交换机只会从连接NAS的那个端口转发过去,不会打扰你电脑上正在看剧的朋友。
这就是交换机相比集线器的核心优势:每个端口是一个独立的冲突域,设备之间通信互不干扰。
跨网段时怎么办?帧过不了路由器
这里有一个很容易混淆的点——MAC地址只在同一个局域网内有效。
你的电脑发给路由器的帧,源MAC是你的电脑,目标MAC是路由器的局域网接口。但路由器拿到帧之后,会拆掉这个帧,取出里面的IP数据包,然后根据目标IP决定从哪个接口转发出去。
路由器转发时,会用新的源MAC和目标MAC重新封装成一个新的帧。
换句话说:
你的电脑 → 路由器:源MAC=你的电脑,目标MAC=路由器
路由器 → 互联网另一端的设备:源MAC=路由器外网口,目标MAC=下一跳
每一跳,MAC地址都会变,但IP地址在整个传输过程中基本保持不变(除了NAT的情况)。
这就像信件从北京寄到纽约:信封上的寄件人和收件人会一路变更(每经过一个中转站就重新贴标签),但信纸上的内容(IP数据包)始终不变。
如果目标MAC找不到怎么办?
交换机收到一帧,发现MAC地址表里没有对应的端口,它会怎么做?
泛洪(Flooding)——把帧从除接收端口外的所有端口转发出去。
这就是为什么你在局域网里抓包时,能抓到ARP广播请求——目标MAC是 FF:FF:FF:FF:FF:FF,这是广播地址,意思是”所有人听着,我说的是你们大家”。
交换机收到广播帧,也会泛洪。这是协议设计的一部分,保证设备总能找到对方。
一个完整的通信过程,串起来看
把上面的所有环节串在一起,假设你的电脑(192.168.1.10,MAC AA:AA:AA:AA:AA:AA)要给路由器(192.168.1.1,MAC BB:BB:BB:BB:BB:BB)发数据:
第一步:ARP请求(广播)
目标MAC: FF:FF:FF:FF:FF:FF(广播)
源MAC: AA:AA:AA:AA:AA:AA
ARP请求: "谁有 192.168.1.1?告诉我你的MAC!"
交换机收到后泛洪,路由器收到后回应。
第二步:ARP应答(单播)
目标MAC: AA:AA:AA:AA:AA:AA
源MAC: BB:BB:BB:BB:BB:BB
ARP应答: "我是 192.168.1.1,我的MAC是 BB:BB:BB:BB:BB:BB"
你的电脑把这条记录存进ARP缓存。
第三步:封装帧,发送数据
目标MAC: BB:BB:BB:BB:BB:BB
源MAC: AA:AA:AA:AA:AA:AA
类型: 0x0800(表示里面是IPv4数据包)
数据: [IP头部 + TCP头部 + 你的应用数据]
FCS: [校验码]
第四步:交换机转发
交换机查到 BB:BB:BB:BB:BB:BB 在端口2,只从那个端口转发出去,路由器收到。
为什么有些帧会被丢弃?CRC校验在保护你
帧末尾的FCS(帧校验序列)不是一个可有可无的东西。
数据在网线里传输时,会受到电磁干扰、串扰、信号衰减等各种影响,有可能某个比特被翻反了。交换机或接收设备在收到帧后,会重新计算校验值,如果和FCS不一致,就直接丢弃,不发任何回应。
上层协议(比如TCP)会发现数据没到,自动重传。
这是一种”不完美但可靠”的策略——数据链路层只管保证这一跳不出错,错了就丢掉让上层来补救。简单、高效、分工明确。
如果你想在电脑上亲眼看看这些帧
你可以用 tcpdump(macOS/Linux)或 Wireshark(全平台)来抓取局域网里的真实帧:
# 抓取局域网所有数据
sudo tcpdump -i any -c 20
# 只看ARP请求
sudo tcpdump arp
你会看到类似这样的输出:
14:32:01.123456 AA:AA:AA:AA:AA:AA > FF:FF:FF:FF:FF:FF, ethertype ARP (0x0806), length 42:
Request who-has 192.168.1.1 tell 192.168.1.10
每一行就是一个真实的帧,你能看到源MAC、目标MAC、协议类型,以及里面携带的信息。这种”亲眼所见”的感觉,比任何比喻都来得真实。
总结一下核心逻辑
数据链路层的工作,归根结底就三件事:
第一,识别设备。 用MAC地址给每台设备一个唯一的本地标识。
第二,封装数据。 把上层交下来的数据包包进帧里,加上源/目标MAC、类型和校验码,让数据能安全地上路。
第三,本地交付。 通过交换机学习MAC地址和端口对应关系,精准地把帧送到正确的设备,而不是无差别广播。
ARP协议充当了IP地址到MAC地址的翻译官,交换机充当了智能分拣员,FCS充当了质量检查员。它们各司其职,共同保证了局域网内数据的准确投递。
网络世界之所以稳定可靠,不是靠某个单一技术,而是靠这一层层精密配合的机制。理解了数据链路层的工作原理,你再看网络故障排查、抓包分析、甚至网络安全相关的内容,都会有一个更扎实的基础。