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 秒实验
- 想一下:能 ping 通 IP 但打不开网页,最可能是哪个协议出问题?
- 想看一下:本机
arp -a里网关那条在不在? - 想一下:为什么「169.254 开头」意味着 DHCP 失败了?
常见误区
- 以为「IP 协议负责可靠传输」。 不负责,它只尽力而为,可靠性是 TCP 的事。
- 以为「能 ping 通就说明网络没问题」。 只说明 IP 层通,DNS、端口、应用都可能还坏着。
- 以为「这些协议可有可无」。 缺一个就有一类故障,症状还各不相同。
自测三问(点开对答案)
1. IP 协议自己负责哪件事? —— **按目的 IP 地址把包往下一跳送**,不保证送达、顺序、不重复。 2. DNS、ARP、ICMP、DHCP 分别补了什么? —— **名字变地址、地址变 MAC、错误通知、自动配置。** 3. 为什么这些功能不直接做进 IP? —— **因为它们只在少数场景需要**,塞进去等于让所有包买单。下一节从一个最小的问题开始:IP 地址为什么记不住。
- ☐ (本节完,下一节 5.2.1 IP地址不便记忆)