📚 第五章 IP协议相关技术
📄 一句话概括

IP 只解决「把包送到」,配套的事它一概不管:名字、硬件地址、错误、配置都得别人来。 所以「能上网」其实是「一堆协议配合的结果」,不是 IP 一个人的功劳。

📝 本节和前面几节的关系

第四章讲完了 IP 本身,这一章讲「围着它转的那些协议」。 4.2.3 讲过「抽象化」,这里看抽象之后还漏了什么。

一、IP 只管一件事

它的职责可以一句话说完:拿着目的 IP 地址,把包往下一跳送,直到送到。 不保证送到、不保证顺序、不保证不重复。

要做的事 IP 管不管 谁来管
名字变地址 不管 DNS
地址变 MAC 不管 ARP
出错了通知 不管 ICMP
自动配地址 不管 DHCP
地址不够用 不管 NAT

五行都是「IP 故意不管」的事,不是它做不到,是「分层」要求它别管。 因为一旦管了,换一种链路或换一种应用就得改协议。 这张表就是本章的目录:后面五节一个一个补上。

二、少一个会怎样

缺任何一个,症状都不一样,这也是排查的线索:

缺什么 症状 怎么验证
DNS 能 ping IP,打不开网页 nslookup 域名
ARP 网关都 ping 不通 arp -a 看表
DHCP 地址是 169.254 开头 ipconfig 看租约
NAT 内网通,出不去 tracert 看断在哪

第三行那个 169.254 开头很典型:它是「自动私有地址」(APIPA), 意思是「我没拿到 DHCP 的地址,自己随便挑了一个」。 看到这个开头,基本可以直接断定「DHCP 没成功」。 第四行的「内网通、出不去」也很典型: 能 ping 网关说明二层没问题,出不去说明 NAT 或路由有问题。 这两件事分开验证,比一股脑重装系统快得多。

三、为什么它们不合并进 IP

一个自然的疑问是「为什么不干脆都塞进 IP」。答案在「谁需要它」这三个字上:

协议 谁需要 塞进 IP 的后果
DNS 只有人和应用需要 路由器白解析一遍
ARP 只有最后一跳需要 跨网段白算一遍
DHCP 只有开机时需要 每个包都带着配置

三行都是「部分场景需要」:塞进 IP 就等于「让所有包为少数场景买单」。 这正是 IPv6 把「选项」改成「扩展首部」的理由——需要才带,不需要就没有开销。 所以「协议分层」不是为了好看:它是「让每种需求只在需要的地方出现」的工程手段。

四、动手 Demo:一次 ping 背后有几个协议

一条最简单的 ping,牵动 DNS、ARP、IP、ICMP 和路由表五样东西。 注意实测输出里的 TTL=128,它说明这个包一跳都没过。

import subprocess
out = subprocess.run('ping -n 1 127.0.0.1', shell=True,
                     capture_output=True).stdout.decode('gbk')
print(out)

实跑输出:

--------------------------------------------------------------------
一次 ping 背后有几个协议
--------------------------------------------------------------------
**`ping` 看起来最简单,其实一次要牵动五六个协议。**
**少一个,这条命令就通不了。**

  协议           这一环干什么             什么时候用
  ------------------------------------------------------------
  **DNS**        **把域名变成 IP**        **ping 域名时需要**
  **ARP**        **把 IP 变成 MAC**       **同网段时必须**
  **IP**         **负责把包送到**         **一直需要**
  **ICMP**       **回显请求与应答**       **ping 本身就是它**
  **路由表**     **决定从哪个口出去**     **一直需要**

**实测一条最简单的**:
**来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128**
**数据包: 已发送 = 1,已接收 = 1,丢失 = 0 (0% 丢失),**

**注意 `TTL=128`**:
**这是 Windows 的默认初始值,收到时还是 128**——**说明这一路上一个路由器都没经过。**
**如果 TTL 变成 127,就说明过了一台设备。**

**所以「能不能通」这一个问题的排查顺序是固定的**:
**先 ping 127.0.0.1(协议栈)、再 ping 网关(链路)**,
**再 ping 8.8.8.8(出口)、最后 ping 域名(DNS)。**
**每一步排除一层,比乱试快得多。**

为什么用 127.0.0.1 做第一次测试:这个地址不出网卡,只走协议栈。 所以它通了,说明「TCP/IP 装好了」;它不通,说明「系统本身有问题」。 这是排查的第一步,也是唯一一步不依赖外部条件的测试。 TTL=128 这个细节值得多说:Windows 默认初始 TTL 是 128,Linux 是 64,网络设备常是 255。 所以「TTL 是多少」有时能反推「对面是什么系统」——这也是端口扫描工具判断操作系统的依据之一。 输出里那行「数据包: 已发送 = 1,已接收 = 1,丢失 = 0」 看起来只是统计,其实是最有用的信息:「丢失 = 0」证明双向都通(请求出去了、应答回来了)。 如果「已发送 1、已接收 0」,说明要么去不了,要么回不来。

30 秒实验

  1. 想一下:能 ping 通 IP 但打不开网页,最可能是哪个协议出问题?
  2. 想看一下:本机 arp -a 里网关那条在不在?
  3. 想一下:为什么「169.254 开头」意味着 DHCP 失败了?

常见误区

  1. 以为「IP 协议负责可靠传输」。 不负责,它只尽力而为,可靠性是 TCP 的事。
  2. 以为「能 ping 通就说明网络没问题」。 只说明 IP 层通,DNS、端口、应用都可能还坏着。
  3. 以为「这些协议可有可无」。 缺一个就有一类故障,症状还各不相同。
自测三问(点开对答案) 1. IP 协议自己负责哪件事? —— **按目的 IP 地址把包往下一跳送**,不保证送达、顺序、不重复。 2. DNS、ARP、ICMP、DHCP 分别补了什么? —— **名字变地址、地址变 MAC、错误通知、自动配置。** 3. 为什么这些功能不直接做进 IP? —— **因为它们只在少数场景需要**,塞进去等于让所有包买单。

下一节从一个最小的问题开始:IP 地址为什么记不住。

相关笔记