网络知识总库

Book Notes · 04 / 14 · TCP/IP

TCP/IP详解 卷1
协议精读笔记

Stevens 的方法是“逐包实证”:把抓包中的每个字段、每次序号变化都还原成协议状态。 本页沿协议族组织九章, 配合报文交互图, 练习从线上的证据反推实现行为。

作者 W. Richard Stevens / Kevin Fall 难度 进阶 建议用时 三周 笔记形式 逐包实证

全书骨架:从抓包证据反推状态机

阅读 Stevens 的秘诀不是背 RFC, 而是给每个现象找证据:谁发包、字段如何变化、计时器何时启动、下一包为何出现。 九章沿着一次连接的生命周期展开。

链路帧 → IP/ARP → ICMP 诊断 → UDP/DNS → TCP 状态 → 重传·拥塞·保活
FIG.0 — 逐包阅读路线:从二层头部一路跟到 TCP 时钟
证据优先

先画出包序列, 再解释 API;同一现象必须能在字段或计时器上找到依据。

状态机思维

TCP 的每个标志位都推动状态转换, 异常包是状态机的输入而非“噪声”。

时间轴

超时、RTT、退避与保活都发生在时间上;没有时间轴就无法解释重传。

跨层校验

MAC、IP、端口和序号应彼此一致, 抓包时先检查封装关系再下结论。

01

概述与链路层:先看见一帧

先建立抓包视角:链路帧是观察协议栈的入口, 地址、类型与校验把一次发送限定在相邻接口之间。

从接口开始

每个网络接口拥有链路地址和 MTU。 抓包工具看到的帧可能被硬件卸载、聚合或过滤, 读者要知道观测点在哪里。

以太网帧的证据

目的/源 MAC 和类型字段告诉我们下一层是谁;广播目的地暗示邻居发现或地址解析, 而非普通单播。

环回与本地主机

发往本机的流量可能绕过物理网卡, 环回接口仍经过协议层。 对比环回与真实接口能区分应用问题和链路问题。

应用数据 → IP 包 → 以太网头 → FCS → 线路
FIG.1 — 逐包观察本章的关键边界
易错点:抓包点不一定看到真实线上所有字段;硬件卸载会让校验和或分段看起来“不完整”。
02

IP 与编址:数据报的身份

IP 章节的重点是把地址、路由和分片放进抓包时间线:一个数据报如何被识别、转发并在必要时拆分。

地址与路由

源/目的地址是端到端身份, 路由器根据目的前缀选出口。 抓包中 TTL 的递减可证明数据报经过了几跳。

头部字段

版本、长度、协议号、标识、片偏移和校验和各有观察用途。 协议号把 IP 负载交给 UDP、TCP 或 ICMP。

分片的包序列

大报文超出 MTU 时会产生多个片段;除首片外片段没有完整传输层头。 重组失败通常表现为上层超时。

IP 包 1 / offset 0 ‖ IP 包 2 / offset n ‖ 目的端重组
FIG.2 — 逐包观察本章的关键边界
易错点:不要把每个 IP 包都当成一个 TCP 段;分片后只有首片携带传输层头部。
03

ARP 与 DHCP:地址从哪里来

主机刚接入网络时, 既没有邻居 MAC, 也可能没有自己的 IP。 ARP 与 DHCP 通过广播和应答完成这两种发现。

ARP 请求与应答

请求帧以广播发送, 目标主机在应答中给出自己的 MAC。 观察缓存可解释为何后续数据包不再广播。

DHCP 四步

客户端发现服务器、请求配置、服务器确认。 报文通常承载在 UDP 上, 广播阶段依赖特殊源/目的地址。

租约与更新

地址是租约而非永久所有权;客户端在时间过半后尝试续租, 失败时仍可短暂使用旧配置。

DHCPDISCOVER → DHCPOFFER → DHCPREQUEST → DHCPACK
FIG.3 — 逐包观察本章的关键边界
易错点:看到 DHCP 报文不等于看到最终应用流量;先确认端口 67/68 与广播标志, 再判断阶段。
04

ICMP、Ping 与 Traceroute:让网络自报家门

ICMP 把不可达、超时和回显结果带回端点。 Ping 测可达与往返时间, Traceroute 则利用 TTL 逐步揭示路径。

回显报文

Ping 请求和应答包含标识与序号, 便于把回答和请求配对。 时间戳由工具记录, 反映的是完整往返而非单向链路。

TTL 逐步探路

发送不同 TTL 的探测包, 沿途过期的路由器返回超时报文;最终目的地返回端口不可达或回显应答。

错误不等于故障

防火墙可能过滤 ICMP, 路径仍能承载 TCP。 诊断结论必须结合多种协议与多个探测点。

TTL=1 探测 → 路由器超时 → TTL=2 探测 → 目标回应
FIG.4 — 逐包观察本章的关键边界
易错点:Traceroute 显示的是“回应了探测的路径”, 不一定等于业务 TCP 的完整路径。
05

UDP 与 IP 分片:短报文也有边界

UDP 章节把端口复用、校验和与 IP 分片放在同一张图里, 提醒我们消息边界和路径 MTU 是不同层的问题。

端口与伪首部

UDP 长度定义报文边界, 校验和覆盖伪首部以绑定源/目的地址, 减少错投。

分片的风险

任一片丢失都会让完整 UDP 报文无法交付;中间设备还可能对分片过滤或限速。

应用层补救

DNS 等应用控制报文尺寸, 或改用 TCP/更现代的传输协议避免依赖分片。

UDP 报文 → 超过 MTU → IP 分片 A ‖ IP 分片 B → UDP 交付
FIG.5 — 逐包观察本章的关键边界
易错点:UDP 报文长度字段属于传输层;IP 总长度属于网络层, 两个长度不要混读。
06

DNS:从查询报文读出名字解析

DNS 的逐包阅读要点是事务 ID、标志位、问题与资源记录。 递归服务器替客户端追问权威服务器, 并将结果缓存。

查询与回答

客户端发出问题, 回答携带一个或多个记录。 A/AAAA 给地址, CNAME 表示别名, TTL 决定缓存寿命。

递归与迭代

递归服务器对客户端负责完整答案;它可能先问根、顶级域和权威服务器, 再把结果返回。

失败与降级

NXDOMAIN、SERVFAIL、超时分别意味着不同故障路径。 抓包时要区分权威否定与递归服务器暂时失败。

Stub resolver → 递归 DNS → 根 / TLD → 权威 DNS → Answer + TTL
FIG.6 — 逐包观察本章的关键边界
易错点:DNS 使用 UDP 很常见但并非绝对;响应过大、区域传送或加密传输可能切换到 TCP 或其他封装。
07

TCP 连接管理:三次握手到四次挥手

把 TCP 当成状态机阅读:SYN、ACK、FIN 和 RST 每个标志都对应状态转换, 四元组定义一条连接。

三次握手

客户端 SYN 携带初始序号, 服务器 SYN+ACK 同时确认并提供自己的序号, 客户端 ACK 完成同步。

数据与确认

ACK 号表示下一个期待的字节。 重复 ACK 暗示缺口, 窗口字段表达接收能力;抓包可由此推断发送端状态。

关闭与复位

FIN 代表半关闭, RST 立即终止。 TIME-WAIT 让旧报文自然过期, 避免新连接误收。

SYN → SYN,ACK → ACK → DATA / ACK → FIN → FIN,ACK
FIG.7 — 逐包观察本章的关键边界
易错点:握手成功只证明传输层建立, 不证明应用服务已接受正确请求;还需观察后续数据或 RST。
08

TCP 超时与重传:从时钟读可靠性

可靠性来自计时器和确认反馈。 Stevens 通过抓包展示 RTO 如何根据 RTT 估算, 丢包后如何指数退避。

RTT 与 RTO

发送段时记录时间, 收到新 ACK 后估算往返时间并设置重传超时。 测量需避开重传样本, 避免把延迟放大。

快速重传

连续重复 ACK 表明接收端看到后续数据但缺少中间段, 发送端可不等计时器直接重传。

退避与探测

超时后降低发送节奏并逐步延长等待, 网络恢复后再谨慎增加。 抓包时间轴应标出每次发送与 ACK。

段 N → (丢失) … 重复 ACK×3 → 快速重传 N → 新 ACK
FIG.8 — 逐包观察本章的关键边界
易错点:不能把“看到重传”直接归因于拥塞;也可能是乱序、无线丢帧或接收端延迟确认。
09

TCP 拥塞控制与保活:与网络共同呼吸

最后一章把发送端窗口拆为接收窗口与拥塞窗口, 并讨论连接长期空闲时如何探测对端仍在。

慢启动与拥塞避免

新连接从较小拥塞窗口开始, 收到 ACK 后快速增长;达到阈值后转为较慢的线性增长。 丢包会降低窗口并重新探测容量。

公平与确认时钟

ACK 到达节奏成为发送时钟, 窗口限制在途数据。 不同流共享瓶颈时, 控制算法努力避免一条流独占。

保活与应用心跳

保活探测针对长时间无数据的连接, 帮助发现失联对端;应用心跳则可携带业务语义, 二者不能混为一谈。

cwnd 小 → 指数增长 → 阈值 → 线性增长 → 丢包后回退 ↺ 再探测
FIG.9 — 逐包观察本章的关键边界
易错点:拥塞窗口不是接收窗口;前者反映网络容量估计, 后者反映对端缓存, 两者共同限制发送量。

读后自测 · 9 题

1. 为什么从链路帧开始读抓包?
它明确了相邻接口和下一层类型, 是判断封装边界与广播范围的证据。
2. TTL 在逐包分析中能说明什么?
每跳递减, 可用于确认转发次数并发现环路或路径变化。
3. ARP 与 DHCP 分别解决什么?
ARP 把本地 IP 映射为链路地址;DHCP 为主机取得 IP、网关、DNS 等配置。
4. Traceroute 的超时报文从哪里来?
探测包 TTL 归零的中间路由器生成 ICMP 超时并返回。
5. 为什么 UDP 分片容易造成整体丢失?
任一片缺失都无法重组完整 UDP 报文, 传输层没有独立片段确认。
6. TCP ACK 号表示什么?
接收端期待的下一个字节序号, 隐含此前字节已按序收到。
7. 何时会触发快速重传?
收到足够多重复 ACK, 表明中间段缺失但后续段已到达。
8. 拥塞窗口和接收窗口差异?
拥塞窗口估计网络承载能力, 接收窗口报告对端缓存空间。
9. 保活和应用心跳是否相同?
不相同;保活是传输层存活探测, 心跳可承载业务状态与超时策略。