ARP 地址解析协议详解

1. 引言

在 TCP/IP 网络中,主机之间通信离不开两个关键地址:IP 地址 (网络层逻辑地址)和 MAC 地址(数据链路层物理地址)。当一台主机要向同一局域网内的另一台主机发送数据时,它知道对方的 IP 地址却不知道对方的 MAC 地址,而数据链路层的以太网帧恰恰要求填充目的 MAC 地址才能被网卡接收。

解决"已知 IP 地址、求解 MAC 地址"这一问题的,正是 ARP(Address Resolution Protocol,地址解析协议)。本文将从工作层级、机制细节、流程细节与帧格式四个维度,系统梳理 ARP 的工作原理。

2. ARP 的工作层级

严格来说,ARP 是一个非常"特殊"的协议,因为它恰好工作在网络层与数据链路层的交界处。

2.1 在 TCP/IP 模型中的位置

TCP/IP 四层模型中,ARP 通常被归入网络接口层(Network Access Layer),与以太网、MAC 地址处于同一层级,但它的报文内容(IP 地址)又属于网络层的范畴。

很多教材将 ARP 描述为工作在 OSI 参考模型的 第 2 层 数据链路层 和第 3 层 网络层之间,因此也被形象地称为"2.5 层协议":

层次 典型内容 与 ARP 的关系
网络层(L3) IP 地址、路由 ARP 要解析的目标信息来自 IP 层
数据链路层(L2) MAC 地址、以太网帧 ARP 报文最终封装在以太网帧中传输

2.2 ARP 与以太网帧的关系

ARP 报文并不能独立在网络上传输,它必须被封装在以太网帧的数据部分中。以太网帧头中有一个类型字段(EtherType) ,当值为 0x0806 时,表示该帧承载的是 ARP 报文;值为 0x0800 时则表示承载的是 IPv4 报文。这个字段也成为接收方区分 ARP 与其他上层协议的重要依据。

3. ARP 的机制细节

3.1 核心思想

ARP 的核心机制是在同一广播域内进行 "询问---应答":

  1. 发送方不知道目标 MAC 地址时,广播一个 ARP 请求;
  2. 广播域内所有主机都会收到该请求;
  3. 只有 IP 地址匹配的主机才单播回应自己的 MAC 地址。

3.2 请求与应答方式

  • ARP 请求 :以广播 方式发送,目的 MAC 地址为全 1 的 ff:ff:ff:ff:ff:ff,即:谁拥有这个 IP,请告诉我你的 MAC。
  • ARP 应答 :以单播方式发送,直接回给请求发起方的 MAC 地址。

3.3 ARP 缓存表

如果每次通信都要先广播询问,网络开销会非常大。因此每台主机会维护一张 ARP 缓存表(ARP Cache) ,记录 IP 地址与 MAC 地址的映射关系,并设置老化时间:

  • 查表命中且未过期 → 直接使用缓存中的 MAC 地址;
  • 查表未命中或已过期 → 发起新的 ARP 请求。

在 Linux 中可使用 arp -n 或 ip neigh show 查看缓存:

bash 复制代码
$ ip neigh show
192.168.1.1 dev eth0 lladdr 00:0c:29:3a:1b:2c REACHABLE

3.4 免费 ARP(Gratuitous ARP)

免费 ARP 是一种特殊用途的 ARP,主机主动广播 "我的 IP 是我的 MAC",其作用包括:

  • 检测 IP 地址冲突:若收到其他主机的应答,说明该 IP 已被占用;
  • 更新其他主机的 ARP 缓存:常用于设备切换或 MAC 地址变更后主动通告。

3.5 代理 ARP(Proxy ARP)

当两台主机不在同一网段、但中间设备开启了代理 ARP 时,路由器会代替目标主机以自己的 MAC 地址回应 ARP 请求。发送方误以为目标就在本地,从而将帧发给路由器,由路由器继续转发。这一机制用于兼容早期不支持子网划分的终端。

4. ARP 的流程细节

本节以一个典型场景为例:主机 A(192.168.1.10)要向同一网段的主机 B(192.168.1.20)发送数据。

4.1 整体流程

#mermaid-svg-tifkD7OxjJbrBxN5{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-tifkD7OxjJbrBxN5 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-tifkD7OxjJbrBxN5 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-tifkD7OxjJbrBxN5 .error-icon{fill:#552222;}#mermaid-svg-tifkD7OxjJbrBxN5 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-tifkD7OxjJbrBxN5 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-tifkD7OxjJbrBxN5 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-tifkD7OxjJbrBxN5 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-tifkD7OxjJbrBxN5 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-tifkD7OxjJbrBxN5 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-tifkD7OxjJbrBxN5 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-tifkD7OxjJbrBxN5 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-tifkD7OxjJbrBxN5 .marker.cross{stroke:#333333;}#mermaid-svg-tifkD7OxjJbrBxN5 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-tifkD7OxjJbrBxN5 p{margin:0;}#mermaid-svg-tifkD7OxjJbrBxN5 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-tifkD7OxjJbrBxN5 .cluster-label text{fill:#333;}#mermaid-svg-tifkD7OxjJbrBxN5 .cluster-label span{color:#333;}#mermaid-svg-tifkD7OxjJbrBxN5 .cluster-label span p{background-color:transparent;}#mermaid-svg-tifkD7OxjJbrBxN5 .label text,#mermaid-svg-tifkD7OxjJbrBxN5 span{fill:#333;color:#333;}#mermaid-svg-tifkD7OxjJbrBxN5 .node rect,#mermaid-svg-tifkD7OxjJbrBxN5 .node circle,#mermaid-svg-tifkD7OxjJbrBxN5 .node ellipse,#mermaid-svg-tifkD7OxjJbrBxN5 .node polygon,#mermaid-svg-tifkD7OxjJbrBxN5 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-tifkD7OxjJbrBxN5 .rough-node .label text,#mermaid-svg-tifkD7OxjJbrBxN5 .node .label text,#mermaid-svg-tifkD7OxjJbrBxN5 .image-shape .label,#mermaid-svg-tifkD7OxjJbrBxN5 .icon-shape .label{text-anchor:middle;}#mermaid-svg-tifkD7OxjJbrBxN5 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-tifkD7OxjJbrBxN5 .rough-node .label,#mermaid-svg-tifkD7OxjJbrBxN5 .node .label,#mermaid-svg-tifkD7OxjJbrBxN5 .image-shape .label,#mermaid-svg-tifkD7OxjJbrBxN5 .icon-shape .label{text-align:center;}#mermaid-svg-tifkD7OxjJbrBxN5 .node.clickable{cursor:pointer;}#mermaid-svg-tifkD7OxjJbrBxN5 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-tifkD7OxjJbrBxN5 .arrowheadPath{fill:#333333;}#mermaid-svg-tifkD7OxjJbrBxN5 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-tifkD7OxjJbrBxN5 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-tifkD7OxjJbrBxN5 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tifkD7OxjJbrBxN5 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-tifkD7OxjJbrBxN5 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tifkD7OxjJbrBxN5 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-tifkD7OxjJbrBxN5 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-tifkD7OxjJbrBxN5 .cluster text{fill:#333;}#mermaid-svg-tifkD7OxjJbrBxN5 .cluster span{color:#333;}#mermaid-svg-tifkD7OxjJbrBxN5 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-tifkD7OxjJbrBxN5 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-tifkD7OxjJbrBxN5 rect.text{fill:none;stroke-width:0;}#mermaid-svg-tifkD7OxjJbrBxN5 .icon-shape,#mermaid-svg-tifkD7OxjJbrBxN5 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tifkD7OxjJbrBxN5 .icon-shape p,#mermaid-svg-tifkD7OxjJbrBxN5 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-tifkD7OxjJbrBxN5 .icon-shape .label rect,#mermaid-svg-tifkD7OxjJbrBxN5 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tifkD7OxjJbrBxN5 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-tifkD7OxjJbrBxN5 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-tifkD7OxjJbrBxN5 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 命中且未过期
未命中
否
是
主机 A 要发送数据给 192.168.1.20
查询 ARP 缓存表
直接使用缓存 MAC 封装以太网帧
广播 ARP 请求
局域网内所有主机接收请求
主机 IP 是否匹配 192.168.1.20
丢弃请求,不回应
主机 B 单播 ARP 应答(携带 MAC)
主机 A 更新 ARP 缓存
主机 A 封装并发送数据帧

4.2 详细步骤

  1. 主机 A 检查 ARP 缓存:查找 192.168.1.20 对应的 MAC 地址。若存在且未过期,直接进入第 6 步。
  2. 广播 ARP 请求 :缓存未命中,主机 A 构造 ARP 请求报文,源 IP 为 192.168.1.10、源 MAC 为主机 A 的 MAC,目标 IP 为 192.168.1.20,目标 MAC 为全 0。该报文封装在以太网帧中,目的 MAC 填 ff:ff:ff:ff:ff:ff 后广播出去。
  3. 所有主机接收并判断:同一广播域内的所有主机(包括主机 B、C 等)网卡都会收到该帧。它们先把帧交给 ARP 模块,检查目标 IP。
  4. 非目标主机丢弃:主机 C 发现目标 IP 不是自己,直接丢弃该 ARP 请求,不做任何回应。
  5. 目标主机应答:主机 B 确认目标 IP 正是自己的 192.168.1.20,于是构造 ARP 应答报文,填入自己的 MAC 地址,并以单播方式回给主机 A。同时主机 B 也会把主机 A 的 IP-MAC 映射存入自己的缓存。
  6. 主机 A 更新缓存并通信:主机 A 收到应答后,将 192.168.1.20 与主机 B 的 MAC 加入缓存,随后即可用该 MAC 封装以太网数据帧并开始正式通信。

4.3 跨网段通信的特殊情况

如果目标主机不在同一网段(例如主机 A(192.168.1.10)要访问 8.8.8.8),ARP 解析的将不是目标主机的 MAC 地址,而是默认网关的 MAC 地址 。下面仍以主机 A 访问 8.8.8.8、默认网关为 192.168.1.1 为例,拆解详细步骤:

  1. 主机 A 判断目标网段 :主机 A 用本机 IP 192.168.1.10、子网掩码与目标 IP 8.8.8.8 做与运算,发现目标 IP 不属于本地网段。
  2. 查路由表确定下一跳 :主机 A 查询路由表,命中默认路由,下一跳地址为默认网关 192.168.1.1。
  3. 检查 ARP 缓存中的网关映射 :主机 A 在 ARP 缓存中查找 192.168.1.1 对应的 MAC 地址。若存在且未过期,直接进入第 6 步。
  4. 广播 ARP 请求解析网关 MAC :缓存未命中时,主机 A 构造 ARP 请求报文,源 IP 为 192.168.1.10、源 MAC 为主机 A 的 MAC,目标 IP 为 192.168.1.1,目标 MAC 为全 0。该报文封装在以太网帧中,目的 MAC 填 ff:ff:ff:ff:ff:ff 后广播出去。
  5. 默认网关应答 :网关收到请求后,确认目标 IP 192.168.1.1 正是自己,于是单播回应自己的 MAC 地址;同时网关也会把主机 A 的 IP---MAC 映射存入自己的 ARP 缓存。
  6. 主机 A 更新网关缓存并发送数据帧 :主机 A 收到网关应答后,将 192.168.1.1 与网关 MAC 写入 ARP 缓存。随后封装以太网帧:目的 MAC 填网关 MAC、源 MAC 填主机 A 的 MAC ,帧内 IP 报文的源 IP 仍为 192.168.1.10,目的 IP 仍为 8.8.8.8。
  7. 网关解封装并继续逐跳转发 :网关剥离帧头后读取 IP 目的地址 8.8.8.8,查询路由表确定下一跳;若下一跳仍通过以太网接口转发,则再次通过 ARP 解析下一跳 MAC,并重新封装新的以太网帧。
  8. 回程流量沿反向路径返回 :8.8.8.8 回包时先回到主机 A 的网关;网关通过 ARP 缓存查到主机 A 的 MAC 后,把回程帧发送给主机 A。整个过程中,IP 源/目的地址保持端到端不变,MAC 地址逐跳变化。

这体现了"IP 负责端到端,MAC 负责逐跳"的分工原则。

5. ARP 帧格式

ARP 报文在以太网中的完整封装结构如下:

text 复制代码
+----------------------------------------------------------------+
|                        以太网帧头                              |
|  目的 MAC(6B) | 源 MAC(6B) | 帧类型(2B, 0x0806)               |
+----------------------------------------------------------------+
|                        ARP 报文(28 字节)                      |
+----------------------------------------------------------------+
|                       帧校验序列 FCS(4B)                        |
+----------------------------------------------------------------+

5.1 ARP 报文字段

以最常见的 IPv4 over Ethernet 场景为例,ARP 报文总长度为 28 字节,字段布局如下:

字段 长度(字节) 说明 IPv4/Ethernet 典型值
硬件类型(Hardware Type) 2 链路层网络类型 1(以太网)
协议类型(Protocol Type) 2 上层协议类型 0x0800(IPv4)
硬件地址长度(HLen) 1 MAC 地址长度 6
协议地址长度(PLen) 1 IP 地址长度 4
操作码(Opcode) 2 请求或应答 1=请求,2=应答
发送方硬件地址(Sender MAC) 6 发送方 MAC 请求方 MAC
发送方协议地址(Sender IP) 4 发送方 IP 请求方 IP
目标硬件地址(Target MAC) 6 目标 MAC 请求时为全 0
目标协议地址(Target IP) 4 目标 IP 待解析的 IP

各字段长度合计:2 + 2 + 1 + 1 + 2 + 6 + 4 + 6 + 4 = 28 字节。

5.2 各字段详解

硬件类型(Hardware Type)

标识底层网络类型,值为 1 表示以太网。其他取值如 6 表示 IEEE 802 网络、15 表示帧中继等。

协议类型(Protocol Type)

标识要解析的上层协议,取值与以太网帧的 EtherType 一致,0x0800 表示 IPv4。若为 IPv6 场景,则不再使用 ARP,而是由 NDP(邻居发现协议) 完成类似功能。

硬件地址长度与协议地址长度

分别标明后续"硬件地址"和"协议地址"字段的字节数。对以太网 + IPv4 而言,分别为 6 和 4。

操作码(Opcode)

用于区分报文类型:

操作码 含义
1 ARP 请求(ARP Request)
2 ARP 应答(ARP Reply)
3 RARP 请求
4 RARP 应答

发送方硬件地址 / 发送方协议地址

记录发送方自身的 MAC 与 IP,既便于接收方直接回复,也便于接收方"顺手"更新自己的 ARP 缓存,减少后续交互。

目标硬件地址 / 目标协议地址

  • 在 ARP 请求中,目标 MAC 通常为全 0(未知),目标 IP 为待解析地址;
  • 在 ARP 应答中,目标 MAC 填充请求方的 MAC,目标 IP 为请求方 IP。

5.3 请求与应答的帧差异

以主机 A(192.168.1.10,MAC aa:aa:aa:aa:aa:aa)请求主机 B(192.168.1.20,MAC bb:bb:bb:bb:bb:bb)为例:

ARP 请求帧关键内容:

text 复制代码
以太网目的 MAC:ff:ff:ff:ff:ff:ff
以太网源 MAC:aa:aa:aa:aa:aa:aa
EtherType:0x0806
硬件类型:1
协议类型:0x0800
操作码:1(请求)
发送方 MAC:aa:aa:aa:aa:aa:aa
发送方 IP:192.168.1.10
目标 MAC:00:00:00:00:00:00
目标 IP:192.168.1.20

ARP 应答帧关键内容:

text 复制代码
以太网目的 MAC:aa:aa:aa:aa:aa:aa
以太网源 MAC:bb:bb:bb:bb:bb:bb
EtherType:0x0806
硬件类型:1
协议类型:0x0800
操作码:2(应答)
发送方 MAC:bb:bb:bb:bb:bb:bb
发送方 IP:192.168.1.20
目标 MAC:aa:aa:aa:aa:aa:aa
目标 IP:192.168.1.10

5.4 抓包观察

使用 Wireshark 抓包时,可直接查看 ARP 报文的各字段。命令行下也可用 tcpdump 过滤 ARP:

bash 复制代码
# 抓取本机收到的所有 ARP 报文
sudo tcpdump -i eth0 arp -nn

典型请求报文输出如下:

text 复制代码
ARP, Request who-has 192.168.1.20 tell 192.168.1.10, length 28

典型应答报文输出如下:

text 复制代码
ARP, Reply 192.168.1.20 is-at bb:bb:bb:bb:bb:bb, length 28

6. ARP 欺骗与防御

6.1 攻击原理

ARP 欺骗(ARP Spoofing,也称 ARP 毒化)的核心在于 ARP 协议本身缺少认证机制 。主机收到 ARP 应答后,通常不会验证应答是否真的来自声称的发送方,而是直接信任其中的「IP---MAC」映射并写入缓存。

攻击者正是利用这一特点,主动向目标主机发送伪造的 ARP 应答 。例如攻击者向受害者宣称"网关 IP 对应我的 MAC 地址",受害者信以为真后,就会把本应发往网关的流量错误地发送给攻击者;攻击者也可以同时欺骗网关,把回程流量引向自己,从而形成中间人攻击(MITM),实现对流量的截获、篡改或丢弃。

text 复制代码
攻击者伪造 ARP 应答:
声称 IP:192.168.1.1(默认网关)
声称 MAC:攻击者的 MAC 地址

6.2 防御措施一:静态 ARP 表

在网络规模较小、地址变更不频繁的环境中,可以直接在主机上配置静态 ARP 条目,将关键 IP 与 MAC 的映射固定下来,避免动态缓存被伪造应答覆盖。

这种方式简单直接,能有效保护网关、核心服务器等关键设备的映射关系;但缺点是配置和运维成本较高,当设备换网卡、迁移 IP 或网络结构发生变化时,需要手动更新所有静态条目,因此不适合大规模动态网络。

6.3 防御措施二:端口安全(DAI)

DAI(Dynamic ARP Inspection,动态 ARP 检测) 是一种部署在交换机上的二层防护机制。交换机维护一张可信的「IP---MAC」绑定表(通常由 DHCP Snooping 生成),并对流经的 ARP 报文进行合法性检查:

  • 报文与绑定表一致 → 正常转发;
  • 报文伪造或与绑定表不一致 → 直接丢弃并记录日志。

DAI 能在攻击流量进入网络前就在接入层被拦截,适合园区网、办公网等可集中管理交换机的场景。由于无需逐台主机配置,维护成本相对较低,但要求交换机支持相关功能并正确部署 DHCP Snooping。

6.4 防御措施三:加密协议(如 IPsec)

相比在二层"堵漏洞",加密协议提供的是纵深防御:即使 ARP 欺骗成功、攻击者截获了流量,也无法直接读懂或篡改通信内容。

IPsec 通过认证头(AH)和封装安全载荷(ESP)为通信提供完整性校验与加密保护;对终端到终端的敏感通信,还可以配合 HTTPS、SSH 等应用层加密,或通过 VPN 建立加密隧道,显著降低 ARP 欺骗造成的信息泄露风险。

需要注意的是,加密协议并不能从根源上阻止 ARP 欺骗的发生,但能大幅提高攻击者利用欺骗流量获取价值的难度,因此通常与静态 ARP、DAI 等措施组合使用,形成多层防线。

7. 总结

ARP 作为 TCP/IP 协议栈中不可缺失的一环,架起了网络层 IP 地址与数据链路层 MAC 地址之间的桥梁:

  • 工作层级 上,它介于网络层与数据链路层之间,报文需封装在以太网帧(EtherType 为 0x0806)中传输;
  • 机制上,通过广播请求、单播应答和本地缓存实现高效解析,并衍生出免费 ARP、代理 ARP 等扩展用法;
  • 流程上,遵循"查缓存 → 广播请求 → 目标应答 → 更新缓存 → 封装通信"的标准路径,跨网段时则解析网关 MAC;
  • 帧格式上,IPv4/Ethernet 场景下的 ARP 报文固定为 28 字节,由硬件类型、协议类型、地址长度、操作码及双方地址字段构成。

掌握 ARP 的工作层级、机制、流程与帧格式,不仅有助于理解局域网通信原理,也能帮助我们在实际网络中识别并防范 ARP 欺骗、二层安全威胁等安全风险。

相关推荐
北京盛世宏博3 小时前
通信异常深度排查:以太网温湿度设备 TCP 粘包、UDP 丢包根治方案
单片机·网络协议·tcp/ip·udp·以太网·传感器·温湿度
上海广测检测科技有限公司3 小时前
消费类智能联网设备安全分级国标征求意见要点解析:三级五维框架与跨境对标逻辑
网络·经验分享
QZ166560951593 小时前
金融数据流转监测排行:从看见到拦截的距离
网络·安全·网络安全·金融
paopaokaka_luck4 小时前
滑雪场管理系统(AI智能助手流式对话,ECharts 运营数据分析、教练、雪具与场地一体化预约,钱包支付退款、订单核销与服务评价)
java·人工智能·spring boot·网络协议·数据分析·echarts
CCblandy5 小时前
HTTP 长连接 3 类故障实测:[WinError 10053]、99 个 TIME_WAIT、69 次多余握手,4 种对策怎么选
后端·python·网络协议·http·云原生·性能优化·架构
雪雪爱冲浪5 小时前
2026 年网络爬虫领域的Puppeteer vs. Playwright
爬虫·网络协议·测试工具·接口隔离原则
zxanz16 小时前
SSL 证书申请下来快吗?
网络·网络协议·ssl
false_or_true6 小时前
一次由 tcp_tw_recycle 引发的“灵异”故障排查:基于双网闸架构的踩坑记
网络·tcp/ip·架构
爱写代码的倒霉蛋6 小时前
我用book-to-skill把尹圣雨的《TCP/IP网络编程》做成了知识库(适合快速入门网络编程)
网络·网络编程·知识库