Linux 数据链路层详解:以太网帧、MAC 地址、MTU 与 ARP 协议
摘要:数据链路层解决的是相邻节点之间如何传递数据的问题。网络层负责规划端到端路径,而数据链路层负责把数据交给"下一跳"。本文围绕以太网展开,讲清以太网帧格式、MAC 地址、MTU 对 IP/UDP/TCP 的影响,以及 ARP 如何完成 IP 地址到 MAC 地址的映射。
前言
前面理解网络层时,我们经常说"路由器把 IP 数据包转发给下一跳"。但这里还有一个更具体的问题:
text
下一跳知道了,网卡到底把这一帧发给谁?
这就是数据链路层要解决的问题。
网络层关注的是从源主机到目标主机的整体路径,数据链路层关注的是同一种链路上相邻设备之间的一段传递。换句话说,IP 地址描述的是"整段旅程"的起点和终点,MAC 地址描述的是"每一小段路"的起点和终点。
一、数据链路层负责什么
数据链路层用于两个相邻设备之间传递数据。这里的相邻,不一定表示两台设备物理上挨着,而是指它们处在同一种链路技术可以直接通信的范围内。
可以把一次跨网络通信拆成这样:
#mermaid-svg-z8xTucwRBlZzOvrr{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-z8xTucwRBlZzOvrr .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-z8xTucwRBlZzOvrr .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-z8xTucwRBlZzOvrr .error-icon{fill:#552222;}#mermaid-svg-z8xTucwRBlZzOvrr .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-z8xTucwRBlZzOvrr .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-z8xTucwRBlZzOvrr .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-z8xTucwRBlZzOvrr .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-z8xTucwRBlZzOvrr .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-z8xTucwRBlZzOvrr .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-z8xTucwRBlZzOvrr .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-z8xTucwRBlZzOvrr .marker{fill:#333333;stroke:#333333;}#mermaid-svg-z8xTucwRBlZzOvrr .marker.cross{stroke:#333333;}#mermaid-svg-z8xTucwRBlZzOvrr svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-z8xTucwRBlZzOvrr p{margin:0;}#mermaid-svg-z8xTucwRBlZzOvrr .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-z8xTucwRBlZzOvrr .cluster-label text{fill:#333;}#mermaid-svg-z8xTucwRBlZzOvrr .cluster-label span{color:#333;}#mermaid-svg-z8xTucwRBlZzOvrr .cluster-label span p{background-color:transparent;}#mermaid-svg-z8xTucwRBlZzOvrr .label text,#mermaid-svg-z8xTucwRBlZzOvrr span{fill:#333;color:#333;}#mermaid-svg-z8xTucwRBlZzOvrr .node rect,#mermaid-svg-z8xTucwRBlZzOvrr .node circle,#mermaid-svg-z8xTucwRBlZzOvrr .node ellipse,#mermaid-svg-z8xTucwRBlZzOvrr .node polygon,#mermaid-svg-z8xTucwRBlZzOvrr .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-z8xTucwRBlZzOvrr .rough-node .label text,#mermaid-svg-z8xTucwRBlZzOvrr .node .label text,#mermaid-svg-z8xTucwRBlZzOvrr .image-shape .label,#mermaid-svg-z8xTucwRBlZzOvrr .icon-shape .label{text-anchor:middle;}#mermaid-svg-z8xTucwRBlZzOvrr .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-z8xTucwRBlZzOvrr .rough-node .label,#mermaid-svg-z8xTucwRBlZzOvrr .node .label,#mermaid-svg-z8xTucwRBlZzOvrr .image-shape .label,#mermaid-svg-z8xTucwRBlZzOvrr .icon-shape .label{text-align:center;}#mermaid-svg-z8xTucwRBlZzOvrr .node.clickable{cursor:pointer;}#mermaid-svg-z8xTucwRBlZzOvrr .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-z8xTucwRBlZzOvrr .arrowheadPath{fill:#333333;}#mermaid-svg-z8xTucwRBlZzOvrr .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-z8xTucwRBlZzOvrr .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-z8xTucwRBlZzOvrr .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-z8xTucwRBlZzOvrr .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-z8xTucwRBlZzOvrr .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-z8xTucwRBlZzOvrr .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-z8xTucwRBlZzOvrr .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-z8xTucwRBlZzOvrr .cluster text{fill:#333;}#mermaid-svg-z8xTucwRBlZzOvrr .cluster span{color:#333;}#mermaid-svg-z8xTucwRBlZzOvrr div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-z8xTucwRBlZzOvrr .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-z8xTucwRBlZzOvrr rect.text{fill:none;stroke-width:0;}#mermaid-svg-z8xTucwRBlZzOvrr .icon-shape,#mermaid-svg-z8xTucwRBlZzOvrr .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-z8xTucwRBlZzOvrr .icon-shape p,#mermaid-svg-z8xTucwRBlZzOvrr .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-z8xTucwRBlZzOvrr .icon-shape .label rect,#mermaid-svg-z8xTucwRBlZzOvrr .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-z8xTucwRBlZzOvrr .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-z8xTucwRBlZzOvrr .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-z8xTucwRBlZzOvrr :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 源主机
路由器 A
路由器 B
目标主机
从网络层看,目标是把数据从源 IP 送到目的 IP;从数据链路层看,每一跳都需要重新封装链路层帧:
| 视角 | 关注点 |
|---|---|
| 网络层 | 源 IP、目的 IP、路由选择 |
| 数据链路层 | 源 MAC、目的 MAC、相邻节点传输 |
所以,IP 地址一般在端到端过程中保持方向意义,而 MAC 地址会随着每一跳转发不断变化。
二、认识以太网
以太网不是某一个具体网络,而是一套局域网技术标准。它既包含数据链路层的内容,也涉及部分物理层内容,例如网络拓扑、访问控制方式、传输速率、线缆规范等。
常见以太网速率包括:
text
10M、100M、1000M
以太网是当前非常常见的局域网技术。和它并列的还可以有令牌环网、无线 LAN 等其他技术。
三、以太网帧格式
以太网传输的基本单位叫帧。典型以太网帧结构如下:
text
+------------+----------+------+----------------+-----+
| 目的 MAC | 源 MAC | 类型 | 数据 | CRC |
+------------+----------+------+----------------+-----+
| 6 字节 | 6 字节 |2字节 | 46~1500 字节 |4字节|
+------------+----------+------+----------------+-----+
各字段含义:
| 字段 | 长度 | 作用 |
|---|---|---|
| 目的 MAC 地址 | 6 字节 | 表示这一帧要交给哪个相邻节点 |
| 源 MAC 地址 | 6 字节 | 表示这一帧从哪个相邻节点发出 |
| 类型 | 2 字节 | 标识上层协议,如 IP、ARP、RARP |
| 数据 | 46~1500 字节 | 承载上层数据 |
| CRC | 4 字节 | 用于帧校验 |
类型字段常见取值:
| 类型值 | 含义 |
|---|---|
0x0800 |
IP 数据报 |
0x0806 |
ARP 请求/应答 |
0x8035 |
RARP 请求/应答 |
以太网帧中的数据部分有最小长度要求。如果上层数据不足 46 字节,需要填充到最小长度。
四、MAC 地址:相邻节点的硬件地址
MAC 地址用于识别数据链路层中相连的节点。它长度为 48 位,也就是 6 字节,通常用十六进制加冒号表示:
text
08:00:27:03:fb:19
一般情况下,MAC 地址在网卡出厂时就被固化,通常具有唯一性。不过虚拟机中的 MAC 地址可能并不是真实硬件地址,也可能出现冲突;部分网卡也允许用户手动配置 MAC 地址。
MAC 地址和 IP 地址的区别
很多初学者会把 MAC 地址和 IP 地址混在一起。它们的定位完全不同:
| 对比项 | IP 地址 | MAC 地址 |
|---|---|---|
| 所属层次 | 网络层 | 数据链路层 |
| 作用范围 | 描述端到端通信方向 | 描述当前链路上的相邻节点 |
| 是否逐跳变化 | 通常不随每一跳变化 | 每经过一跳都会重新封装 |
| 典型问题 | 数据包最终去哪里 | 当前这一帧交给谁 |
举个直观例子:从家里寄快递到外地,IP 地址像最终收件地址,MAC 地址像每一段运输交接时的站点地址。快递最终目的地不变,但每一段交给谁会变。
五、MTU:一帧最多能装多少数据
MTU 是 Maximum Transmission Unit,最大传输单元。它描述某种链路层网络一次最多能承载多少上层数据。
以太网中,数据字段最大是 1500 字节,所以常见以太网 MTU 是:
text
1500 字节
可以把 MTU 理解成快递包裹尺寸限制。不同链路技术的限制可能不同。如果一个数据包从以太网转发到 MTU 更小的链路,就可能需要分片。
查看网卡地址和 MTU:
bash
ifconfig
新系统中也常用:
bash
ip link
六、MTU 对 IP 的影响
由于链路层 MTU 限制,较大的 IP 数据报可能需要分片。分片过程大致如下:
#mermaid-svg-YEmiBX0uZ3qLm2uD{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-YEmiBX0uZ3qLm2uD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YEmiBX0uZ3qLm2uD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YEmiBX0uZ3qLm2uD .error-icon{fill:#552222;}#mermaid-svg-YEmiBX0uZ3qLm2uD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YEmiBX0uZ3qLm2uD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YEmiBX0uZ3qLm2uD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YEmiBX0uZ3qLm2uD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YEmiBX0uZ3qLm2uD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YEmiBX0uZ3qLm2uD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YEmiBX0uZ3qLm2uD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YEmiBX0uZ3qLm2uD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YEmiBX0uZ3qLm2uD .marker.cross{stroke:#333333;}#mermaid-svg-YEmiBX0uZ3qLm2uD svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YEmiBX0uZ3qLm2uD p{margin:0;}#mermaid-svg-YEmiBX0uZ3qLm2uD .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-YEmiBX0uZ3qLm2uD .cluster-label text{fill:#333;}#mermaid-svg-YEmiBX0uZ3qLm2uD .cluster-label span{color:#333;}#mermaid-svg-YEmiBX0uZ3qLm2uD .cluster-label span p{background-color:transparent;}#mermaid-svg-YEmiBX0uZ3qLm2uD .label text,#mermaid-svg-YEmiBX0uZ3qLm2uD span{fill:#333;color:#333;}#mermaid-svg-YEmiBX0uZ3qLm2uD .node rect,#mermaid-svg-YEmiBX0uZ3qLm2uD .node circle,#mermaid-svg-YEmiBX0uZ3qLm2uD .node ellipse,#mermaid-svg-YEmiBX0uZ3qLm2uD .node polygon,#mermaid-svg-YEmiBX0uZ3qLm2uD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YEmiBX0uZ3qLm2uD .rough-node .label text,#mermaid-svg-YEmiBX0uZ3qLm2uD .node .label text,#mermaid-svg-YEmiBX0uZ3qLm2uD .image-shape .label,#mermaid-svg-YEmiBX0uZ3qLm2uD .icon-shape .label{text-anchor:middle;}#mermaid-svg-YEmiBX0uZ3qLm2uD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-YEmiBX0uZ3qLm2uD .rough-node .label,#mermaid-svg-YEmiBX0uZ3qLm2uD .node .label,#mermaid-svg-YEmiBX0uZ3qLm2uD .image-shape .label,#mermaid-svg-YEmiBX0uZ3qLm2uD .icon-shape .label{text-align:center;}#mermaid-svg-YEmiBX0uZ3qLm2uD .node.clickable{cursor:pointer;}#mermaid-svg-YEmiBX0uZ3qLm2uD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-YEmiBX0uZ3qLm2uD .arrowheadPath{fill:#333333;}#mermaid-svg-YEmiBX0uZ3qLm2uD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-YEmiBX0uZ3qLm2uD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-YEmiBX0uZ3qLm2uD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YEmiBX0uZ3qLm2uD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-YEmiBX0uZ3qLm2uD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YEmiBX0uZ3qLm2uD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-YEmiBX0uZ3qLm2uD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-YEmiBX0uZ3qLm2uD .cluster text{fill:#333;}#mermaid-svg-YEmiBX0uZ3qLm2uD .cluster span{color:#333;}#mermaid-svg-YEmiBX0uZ3qLm2uD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-YEmiBX0uZ3qLm2uD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-YEmiBX0uZ3qLm2uD rect.text{fill:none;stroke-width:0;}#mermaid-svg-YEmiBX0uZ3qLm2uD .icon-shape,#mermaid-svg-YEmiBX0uZ3qLm2uD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YEmiBX0uZ3qLm2uD .icon-shape p,#mermaid-svg-YEmiBX0uZ3qLm2uD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-YEmiBX0uZ3qLm2uD .icon-shape .label rect,#mermaid-svg-YEmiBX0uZ3qLm2uD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YEmiBX0uZ3qLm2uD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-YEmiBX0uZ3qLm2uD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-YEmiBX0uZ3qLm2uD :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 较大的 IP 数据报
按 MTU 切成多个分片
每个分片带相同 16 位标识
通过标志位和分片偏移描述位置
接收端按顺序重组
IP 分片会用到 IP 首部中的几个字段:
| 字段 | 作用 |
|---|---|
| 16 位标识 | 同一个原始数据报的多个分片使用相同标识 |
| 标志字段 | 表示是否允许分片、是否还有更多分片 |
| 分片偏移 | 表示当前分片在原始数据报中的位置 |
需要特别注意:只要任意一个分片丢失,接收端重组就会失败。而 IP 层本身不负责重传,这会把问题继续交给上层处理。
七、MTU 对 UDP 的影响
UDP 本身面向数据报,如果 UDP 携带的数据太大,就可能在网络层被拆成多个 IP 分片。
以常见以太网 MTU 1500 为例:
text
最大 UDP 载荷 = 1500 - 20(IP 首部) - 8(UDP 首部) = 1472 字节
如果 UDP 携带的数据超过 1472 字节,就可能被拆成多个 IP 数据报。任意一个分片丢失,整个 UDP 数据报都无法被正确重组。
这也是为什么实际写 UDP 程序时,不建议把单个 UDP 包做得太大。报文越大,分片概率越高,整体丢失概率也越高。
八、MTU 对 TCP 的影响
TCP 的数据段也不能无限大,同样受 MTU 限制。TCP 中有一个和 MTU 密切相关的概念:MSS。
MSS 是 Maximum Segment Size,表示 TCP 单个报文段中应用数据的最大长度。
在以太网 MTU 为 1500 的常见情况下,如果不考虑额外选项:
text
MSS = 1500 - 20(IP 首部) - 20(TCP 首部) = 1460 字节
TCP 建立连接时,双方会在 SYN 报文中写入自己支持的 MSS 值。通信双方得知彼此的 MSS 后,通常选择较小值作为最终 MSS。
这个设计的目标是:尽量让 TCP 段在发送时不触发 IP 分片,从而降低重组失败和性能损耗。
| 概念 | 含义 |
|---|---|
| MTU | 链路层一次可承载的最大上层数据长度 |
| MSS | TCP 单个报文段可承载的最大应用数据长度 |
| 关系 | MSS 通常受 MTU 约束 |
九、ARP 协议:从 IP 找到 MAC
在发送网络数据时,应用程序通常知道目的 IP 和端口,但网卡真正发送以太网帧时,需要目的 MAC 地址。
问题来了:
text
我知道对方 IP,怎么知道对方 MAC?
ARP 就是为了解决这个问题。它建立主机 IP 地址和 MAC 地址之间的映射关系。
ARP 介于网络层和数据链路层之间。它服务于 IP 通信,但发送时又依赖以太网帧广播。
十、ARP 工作流程
假设源主机想知道 192.168.0.1 对应的 MAC 地址,流程如下:
目标主机 本地网段 源主机 目标主机 本地网段 源主机 #mermaid-svg-nC6n7JR1ib1ZDW6J{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-nC6n7JR1ib1ZDW6J .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-nC6n7JR1ib1ZDW6J .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-nC6n7JR1ib1ZDW6J .error-icon{fill:#552222;}#mermaid-svg-nC6n7JR1ib1ZDW6J .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-nC6n7JR1ib1ZDW6J .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-nC6n7JR1ib1ZDW6J .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-nC6n7JR1ib1ZDW6J .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-nC6n7JR1ib1ZDW6J .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-nC6n7JR1ib1ZDW6J .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-nC6n7JR1ib1ZDW6J .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-nC6n7JR1ib1ZDW6J .marker{fill:#333333;stroke:#333333;}#mermaid-svg-nC6n7JR1ib1ZDW6J .marker.cross{stroke:#333333;}#mermaid-svg-nC6n7JR1ib1ZDW6J svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-nC6n7JR1ib1ZDW6J p{margin:0;}#mermaid-svg-nC6n7JR1ib1ZDW6J .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-nC6n7JR1ib1ZDW6J text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-nC6n7JR1ib1ZDW6J .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-nC6n7JR1ib1ZDW6J .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-nC6n7JR1ib1ZDW6J .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-nC6n7JR1ib1ZDW6J .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-nC6n7JR1ib1ZDW6J #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-nC6n7JR1ib1ZDW6J .sequenceNumber{fill:white;}#mermaid-svg-nC6n7JR1ib1ZDW6J #sequencenumber{fill:#333;}#mermaid-svg-nC6n7JR1ib1ZDW6J #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-nC6n7JR1ib1ZDW6J .messageText{fill:#333;stroke:none;}#mermaid-svg-nC6n7JR1ib1ZDW6J .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-nC6n7JR1ib1ZDW6J .labelText,#mermaid-svg-nC6n7JR1ib1ZDW6J .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-nC6n7JR1ib1ZDW6J .loopText,#mermaid-svg-nC6n7JR1ib1ZDW6J .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-nC6n7JR1ib1ZDW6J .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-nC6n7JR1ib1ZDW6J .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-nC6n7JR1ib1ZDW6J .noteText,#mermaid-svg-nC6n7JR1ib1ZDW6J .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-nC6n7JR1ib1ZDW6J .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-nC6n7JR1ib1ZDW6J .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-nC6n7JR1ib1ZDW6J .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-nC6n7JR1ib1ZDW6J .actorPopupMenu{position:absolute;}#mermaid-svg-nC6n7JR1ib1ZDW6J .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-nC6n7JR1ib1ZDW6J .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-nC6n7JR1ib1ZDW6J .actor-man circle,#mermaid-svg-nC6n7JR1ib1ZDW6J line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-nC6n7JR1ib1ZDW6J :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ARP 请求:谁是 192.168.0.1?广播到本地网段ARP 应答:我的 MAC 是 xx:xx:xx:xx:xx:xx
ARP 请求使用广播 MAC 地址:
text
FF:FF:FF:FF:FF:FF
本地网段内所有主机都能收到这个广播,但只有 IP 地址匹配的主机会回复 ARP 应答。
每台主机都会维护 ARP 缓存表,可以通过命令查看:
bash
arp -a
ARP 缓存表中的条目有过期时间。这样做有两个原因:
- 避免每次通信都广播 ARP 请求,提高效率;
- 防止网络环境变化后长期使用过期映射。
十一、ARP 报文格式
ARP 报文中包含硬件类型、协议类型、地址长度、操作类型、发送端地址、目标地址等字段。
简化结构如下:
text
+----------+----------+------+------+
| 硬件类型 | 协议类型 |硬长 |协长 |
+----------+----------+------+------+
| op | 发送端 MAC 地址 |
+----------+-------------------------+
| 发送端 IP 地址 |
+-----------------------------------+
| 目的 MAC 地址 |
+-----------------------------------+
| 目的 IP 地址 |
+-----------------------------------+
关键字段:
| 字段 | 含义 |
|---|---|
| 硬件类型 | 链路层网络类型,1 表示以太网 |
| 协议类型 | 要转换的地址类型,0x0800 表示 IP 地址 |
| 硬件地址长度 | 以太网地址为 6 字节 |
| 协议地址长度 | IPv4 地址为 4 字节 |
| op | 1 表示 ARP 请求,2 表示 ARP 应答 |
在以太网环境中,源 MAC、目的 MAC 会同时出现在以太网首部和 ARP 报文中,看起来有些重复。但 ARP 不是只为以太网设计的,在其他链路层网络中,这些字段仍然有意义。
十二、常见问题与易错点
1. 认为 MAC 地址能跨网络定位目标主机
MAC 地址只解决当前链路上的相邻节点通信。跨网络通信时,真正规划路径的是 IP 和路由表。
2. 把 MTU 和 MSS 混为一谈
MTU 是链路层限制,MSS 是 TCP 数据长度限制。MSS 通常由 MTU 推导出来,但二者不在同一层。
3. UDP 包过大导致丢失概率升高
UDP 数据一旦触发 IP 分片,只要任意分片丢失,整个数据报就无法重组。写 UDP 程序时要控制单包大小。
4. 忽略 ARP 缓存过期
ARP 缓存不是永久有效。网络变化、网卡替换、虚拟机迁移等情况,都可能导致旧映射失效。
5. 误以为 ARP 能跨网段广播
ARP 请求广播只在本地网段内传播。访问外网时,主机通常解析的是网关的 MAC 地址,而不是远端服务器的 MAC 地址。
总结
数据链路层负责相邻节点之间的数据传递。以太网通过帧格式封装目的 MAC、源 MAC、类型、数据和 CRC;MAC 地址用于标识当前链路上的节点;MTU 限制单帧可承载的数据大小,并影响 IP 分片、UDP 报文大小和 TCP MSS;ARP 则负责在本地网段内根据 IP 地址获取 MAC 地址。
把它和网络层放在一起看就很清楚了:IP 决定数据包最终去哪里,路由决定下一跳是谁,数据链路层再把这一跳封装成以太网帧发出去。每经过一跳,链路层首部都会重新封装,而 IP 层的端到端方向仍然保持不变。