CalcGuide · 技术博客主页 / 一页纸学习计划
🔥极高

TCP 与 UDP:从三次握手到拥塞控制

分类:计算机基础 · 路径:docs/topics/tcp-and-udp/README.md

#tcp#udp#quic#congestion-control

理解 TCP 三次握手/四次挥手、滑动窗口、拥塞控制、UDP 适用场景、QUIC 演进

父主题

计算机网络:从物理层到 HTTP/3 的全栈协议与排查

子主题(0)

TCP 与 UDP:从三次握手到拥塞控制

0. 元信息

1. 学习路线

传输层职责与端口
  → UDP 头与无连接语义
  → TCP 头字段
  → 三次握手与四次挥手
  → 状态机与 TIME_WAIT
  → 可靠传输:序列号、ACK、重传
  → 流量控制:滑动窗口与 rwnd
  → 拥塞控制:cwnd、慢启动、拥塞避免
  → 经典算法:Reno / Cubic / BBR
  → UDP 适用场景:DNS / VoIP / 实时游戏
  → QUIC 演进:解决队头阻塞、握手合并
  → Linux 调参与抓包综合排障

每一步都要抓一次包。TCP 字段多、背不下来,靠抓包对照才记得住。

2. 阶段周数分配

阶段4 周方案5 周方案备注
1. 传输层与 UDP0.5 周0.5 周UDP 头 + DNS 抓包
2. TCP 头与三次握手0.5 周0.75 周tcpdump -S -nn 抓 SYN/SYN-ACK/ACK
3. 状态机与挥手0.5 周0.75 周11 个状态 + TIME_WAIT 之谜
4. 滑动窗口与重传0.5 周0.75 周rwnd、累积 ACK、选择性重传
5. 拥塞控制1 周1.25 周慢启动、cwnd、四大算法
6. UDP 实战与 QUIC0.5 周0.5 周DNS、NTP、QUIC 抓包
7. 综合排障0.5 周0.5 周ss -tin + iperf3 + tcpdump 联用

3. 九阶段表

阶段核心知识实践产出可观察学会标准
1. 传输层定位端口、socket、多路复用、TCP vs UDP 语义一张 5 元组变化图能解释 TCP 与 UDP 各自解决的什么问题
2. UDP头(length + checksum)、无连接、尽最大努力抓一次 DNS 53/UDP 交互能从抓包看出发送/响应端口和长度
3. TCP 头16 位源/目的端口、32 位序列号、32 位 ACK、头长、flags、window、checksum、urgent抓一次 HTTP 80 连接的三次握手能从 hex 找出 SYN、ACK、seq、ack_seq
4. 三次握手SYN、SYN-ACK、ACK、ISN 随机化、半打开防御抓包 + 解释每一步能解释为什么三次而不是两次
5. 四次挥手FIN、ACK、CLOSE_WAIT、TIME_WAIT、2MSL抓 HTTP 关闭的 FIN 包能解释 TIME_WAIT 多的原因与 SO_REUSEADDR
6. 滑动窗口rwnd、累积 ACK、零窗口、糊涂窗口综合征ss -tin 看窗口大小能解释为什么需要滑动窗口
7. 拥塞控制cwnd、慢启动、拥塞避免、ssthreshss -tin 看 cwnd init能区分 rwnd 与 cwnd
8. 经典算法Tahoe、Reno、Cubic(默认)、BBR同一链路换算法测吞吐能解释 BBR 为什么在丢包网络更优
9. UDP + QUICDNS、QUIC 头、连接迁移、0-RTT、队头阻塞抓一次 HTTP/3 443/UDP能说出 QUIC 相对 TCP+TLS 的核心改进

阶段 9 真实场景:HTTP/3 在公网移动场景下比 HTTP/1.1 + TLS 1.3 over TCP 抗丢包能力强,能从 QUIC 抓包看 connection_id 验证连接迁移。

4. 第一周任务

任务当天交付
Day 1ss -tunlp 看本机监听 socket;netstat -s 看 TCP 重传统计一份监听清单 + TCP 统计
Day 2tcpdump -ni any -nn -S udp port 53 抓一次 dig 请求;看 UDP 头字段DNS 抓包 + 字段标注
Day 3curl http://example.com 同时 tcpdump -ni any -nn -S 'tcp port 80' 抓三次握手三次握手 pcap + seq/ack 标注
Day 4故意 tc qdisc add dev lo root netem loss 30% 制造丢包;tcpdump 看 TCP 重传丢包 + 重传对照记录
Day 5ss -tin 看活跃连接的 cwnd、rwnd、rtt、retrans;阅读 man 7 tcp一份连接参数清单
Day 6iperf3 -s 在两台机器间跑 TCP/UDP 打流;tcpdump -nn -S 同时抓iperf3 报告 + 抓包
Day 7项目:抓一次完整 TCP 生命周期:连接建立 → 传输数据 → 关闭,包含三次握手、数据 ACK、四次挥手完整 pcap + 字段标注 + 复盘

Day 7 拆解

步骤 A —— 最小可用(60 分钟)

  1. tcpdump -ni any -w /tmp/tcp.pcap -nn -S 'tcp and host <target>' 抓 60 秒;
  2. curl http://<target>/ 触发完整连接;
  3. tcpdump -r /tmp/tcp.pcap -nn -S 列出所有包;
  4. 把三次握手和四次挥手的 seq/ack/flags 标到 16 进制输出上。

步骤 B —— 补齐边界(30 分钟)

进阶:稳定通过后,再叠加 tcpdump -nn -S 'tcp[tcpflags] & tcp-syn != 0' 单独看 SYN 包。

5. 阶段通用验收

  1. 不看 RFC 也能画出 TCP 头 20 字节的字段分布;
  2. 用自己的话解释「为什么三次握手」「为什么 TIME_WAIT 等 2MSL」;
  3. 画一张图:建立连接 → 传输数据 → 关闭过程中 seq/ack/window 变化;
  4. 测试异常:SYN 攻击、半打开、RST 强制关闭、零窗口、丢包触发重传;
  5. 准备 3 组自定义数据并贴实际抓包(不同 RTT、不同丢包率、不同 cwnd 算法);
  6. 记录每次抓包的 BPF 过滤器和命令;
  7. 能修改 sysctl 拥塞控制算法并验证切换。

6. 最终验收

7. 综合项目

首选:TCP 链路质量诊断(必做:在两台 Linux 上用 tc netem 注入延迟 / 丢包 / 抖动,用 ss -tin / iperf3 / tcpdump 三件套定位)。

备选

综合项目必做要求:

  1. 场景描述:网络拓扑、预期行为、实际行为;
  2. 工具选择理由:为什么用 ss -tin 而不是 netstat?为什么用 iperf3 而不是 curl
  3. 核心分析:每一次现象的判断依据与根因定位;
  4. 复现脚本:可重复运行的 tc qdisc add / iperf3 / tcpdump 命令;
  5. 边界测试:换丢包率、换 RTT、换 cwnd 算法都验证过;
  6. 运行说明:环境依赖(iproute2tcpdumpiperf3)、复现步骤;
  7. README:项目介绍、目录结构、复盘;
  8. 复盘记录:用时、难点、收获、下一步。

复盘项目交付物统一存到 notes/

本主题贡献

本主题沉淀 TCP 三次握手/四次挥手、滑动窗口与四大拥塞控制算法(Reno/Cubic/BBR),以及 QUIC over UDP 多路复用的工程化观测,所有结论以 tcpdump -nn -S + ss -tin + iperf3 为证据。

职责(3 项)

  1. 抓 TCP 三次握手 SYN/SYN-ACK/ACK 序列、四次挥手 FIN/ACK、ISN 随机化与 TIME_WAIT 行为,能解释为什么 TIME_WAIT 等 2MSL 与 SO_REUSEADDR 的边界,以及 SYN flood 下 tcp_max_syn_backlog + syncookies 的边界;
  2. 区分 rwnd(防接收方被淹)与 cwnd(防网络被淹),用 tc qdisc add 注入丢包验证 Reno/Cubic/BBR 在跨运营商链路的吞吐差异,能解释 BBR 基于带宽×RTT 模型而非丢包事件的抗丢包原理;
  3. 抓 HTTP/3 over QUIC 的 Initial/Handshake 包、CRYPTO 帧与 connection_id,验证连接迁移(换 IP 不重连)与 0-RTT 重放风险,能区分 QUIC stream 隔离与 HTTP/2 单连接多 stream 在队头阻塞上的差异。

交付物(4 项)

  1. 完整 TCP 生命周期 pcap(建立 → 数据 → 关闭),含 SYN、SYN-ACK、ACK、FIN 序列号与 flags 标注(-S 不加会看到相对值 0/1/2);
  2. ss -tin 输出(cwnd/rwnd/rtt/retrans/ssthresh)与 sysctl net.ipv4.tcp_congestion_control 切换记录(cubic ↔ bbr);
  3. iperf3 -P 4 -w 1M 同链路 Cubic vs BBR 30 秒吞吐对比报告,附 RTT/丢包率变量;
  4. HTTP/3 over QUIC 抓包(curl --http3-only -v + SSLKEYLOGFILE 喂 Wireshark),含 connection_id 与 0-RTT Early Data 证据。

指标(3 项)

  1. TIME_WAIT 比例 ≤ 30%(短连接服务开启 net.ipv4.tcp_tw_reuse 后);
  2. TCP 重传率 ≤ 0.5%(netstat -s / ss -tin retrans 采样);
  3. 拥塞控制切换后吞吐提升 ≥ 20%(BBR 相对 Cubic,跨运营商 1% 丢包链路)。

8. 推荐开源资料(按角色分工)

角色资料链接用法
RFC 原文RFC 9293 (TCP)https://www.rfc-editor.org/rfc/rfc9293TCP 现状规范(替代 RFC 793)
RFC 原文RFC 768 (UDP)https://www.rfc-editor.org/rfc/rfc768UDP 全文短,一遍读完
RFC 原文RFC 9000 (QUIC)https://www.rfc-editor.org/rfc/rfc9000QUIC 传输
RFC 原文RFC 5681 (TCP Congestion Control)https://www.rfc-editor.org/rfc/rfc5681拥塞控制经典
RFC 原文RFC 9438 (TCP CUBIC)https://www.rfc-editor.org/rfc/rfc9438当前 Linux 默认算法
论文Jacobson 1988 (Congestion Avoidance)https://ee.lbl.gov/papers/congavoid.pdf慢启动与拥塞避免起源
论文BBR: Congestion-Based Congestion Controlhttps://queue.acm.org/detail.cfm?id=3022184BBR 原理
工具手册iperf3 主页https://iperf.fr/打流与吞吐测量
工具手册man 7 tcpman 7 tcpLinux TCP 实现细节
工具手册ss 命令手册https://man7.org/linux/man-pages/man8/ss.8.html-tin 等参数
中文讲解美团技术团队「TCP 那些事儿」https://tech.meituan.com/国内高质量 TCP 分析
抓包练习Wireshark 官方样例 pcaphttps://wiki.wireshark.org/SampleCapturesTCP/UDP 真实报文

许可证提示:Wireshark 样例 pcap 是公开教学资源;iproute2 是 GPL-2.0。复制或参考命令前先确认许可证。

源码阅读时机:Linux TCP 实现源码(net/ipv4/tcp.c / tcp_input.c / tcp_output.c)放到「阶段 5(拥塞控制)」之后再读;RFC 原文从 Day 1 就开始对照,但不要试图一次通读——按当前阶段挑相关章节。

9. 学习资料汇聚(v0.3 自包含)

本节内容基于公开 RFC、Linux 手册与个人整理,标注「由本计划生成」处为计划自写。本节是子主题自包含的最后一节,不再依赖 notes/ 子目录。

9.1 背景与动机

9.2 概念地图

flowchart LR
  App[应用层] --> Socket
  Socket --> TCP[TCP]
  Socket --> UDP[UDP]
  Socket --> QUIC[QUIC / HTTP/3]
  TCP --> State[状态机]
  TCP --> Flow[流量控制 rwnd]
  TCP --> Cong[拥塞控制 cwnd]
  TCP --> Retrans[重传]
  Cong --> Reno[Reno]
  Cong --> Cubic[Cubic]
  Cong --> BBR[BBR]
  UDP --> DNS
  UDP --> RTP[实时音视频]
  QUIC --> Stream[多路复用流]
  QUIC --> 0RTT[0-RTT]
  QUIC --> Migration[连接迁移]
  TCP --> IP
  UDP --> IP
  QUIC --> IP

关系说明:

9.3 基础知识讲解

经典论文 / 经典书籍 / 优秀博客 / 核心人物 / 开发方法 五大类,每类 ≥3 条。

经典论文 / RFC(必读)

资料角色评分链接
RFC 9293 — Transmission Control ProtocolTCP 现状规范5https://www.rfc-editor.org/rfc/rfc9293
RFC 768 — User Datagram ProtocolUDP 全文5https://www.rfc-editor.org/rfc/rfc768
RFC 9000 — QUICQUIC 传输5https://www.rfc-editor.org/rfc/rfc9000
RFC 5681 — TCP Congestion Control拥塞控制经典5https://www.rfc-editor.org/rfc/rfc5681
RFC 9438 — CUBIC当前 Linux 默认算法4https://www.rfc-editor.org/rfc/rfc9438
RFC 6298 — TCP RTO 计算RTO 重传策略4https://www.rfc-editor.org/rfc/rfc6298
Jacobson 1988 Congestion Avoidance慢启动起源5https://ee.lbl.gov/papers/congavoid.pdf
BBR: Congestion-Based Congestion ControlBBR 原理5https://queue.acm.org/detail.cfm?id=3022184

经典书籍(系统化)

资料角色评分链接
《TCP/IP 详解 卷 1:协议》(Richard Stevens)协议层最经典5https://www.amazon.com/TCP-Illustrated-Volume-Protocols/dp/0321336313
《UNIX 网络编程 卷 1》(Stevens)Socket 与协议实现5https://www.unixnetworkprogramming.com/
《计算机网络:自顶向下方法》(Kurose & Ross)教学级系统讲解4https://gaia.cs.umass.edu/kurose_ross/
《Linux 高性能服务器编程》(游双)Linux 网络栈工程4https://book.douban.com/subject/24722642/
《TCP/IP 架构、设计与应用》(Feit)协议族现代视角4https://www.amazon.com/TCP-Architecture-Protocols-Implementation/dp/0070607314

优秀博客(按问题查)

资料角色评分链接
Julia Evans「Networking!」(zines)抓包与命令可视化5https://jvns.ca/networking-zine.pdf
Cloudflare Blog(TCP/QUIC 系列)TCP/QUIC 深入4https://blog.cloudflare.com/tag/tcp/
Marek Majkowski(Cloudflare)Linux 调参与排障4https://blog.cloudflare.com/tag/tcp/
美团技术团队「TCP 那些事儿」中文长文深度解析5https://tech.meituan.com/
APNIC Blog运营商视角 + 排障4https://blog.apnic.net/
张彦飞「TCP 三次握手与四次挥手」中文原理图解3https://yuanfux.github.io/

核心人物(知道谁定的规范)

人物贡献关键出处
Vint CerfTCP/IP 共同设计者1974 论文
Bob KahnTCP/IP 共同设计者1974 论文
Jon PostelRFC 编辑、TCP/UDP 标准化RFC 793/768
Van Jacobson慢启动、拥塞避免、TCP 头压缩1988 论文
Jim GettysBBR 共同提出者1990s HTTP/1.1 设计
Neal CardwellBBR、Linux TCP 调参Linux Kernel 维护者
Yuchung ChengLinux TCP 团队CUBIC 改进
Jana IyengarQUIC 设计IETF QUIC WG 主席

开发方法(动手习惯)

方法适用关键点
抓包驱动学习TCP 任何机制看到 seq/ack/flags 变化比看图快 10 倍
ss -tin 必看实时连接调参抓现场连接的真实 cwnd、rwnd、rtt
tcpdump -nn -S数字不解析不加 -S seq 是相对值,看不出绝对增长
iperf3 打流复现吞吐与延迟客户端/服务端分开跑,记录并发流数
tc netem 注入模拟丢包/延迟永远先在测试环境复现,再回生产
BPF 过滤抓包tcp[tcpflags] & tcp-syn != 0 单看 SYN
man 7 tcp / man 7 ipLinux 实现细节看到 tcp_no_metrics_save 等默认值

缺失部分:tcpdump-dd 输出语法、BPF 字面量在不同 libpcap 版本的差异。本计划不重写工具手册;查 man pcap-filter 即可。

9.4 经典问题与经典案例

#问题为什么会重要最简答案
1TIME_WAIT 太多短连接服务 TIME_WAIT 一旦上万,端口耗尽开启 SO_REUSEADDR、调整 net.ipv4.ip_local_port_range
2SYN flood攻击者只发 SYN 不回 ACK启用 syncookies、合理调 tcp_max_syn_backlog
3队头阻塞(HoL)TCP 丢一包阻塞整条流HTTP/2 多路复用缓解但未根除;QUIC 真正解决
4Nagle 与延迟应答小包合并导致延迟升高关闭 TCP_NODELAY、关闭 TCP_QUICKACK
5零窗口死锁接收方 rwnd=0 后丢了窗口更新持久化零窗口探测 + 可调整 tcp_zero_window_drop
6滑动窗口不前进接收方应用层读慢调大 net.ipv4.tcp_rmem、应用层读优化
7拥塞控制算法选错跨运营商丢包多,Cubic 吞吐崩切 BBR:sysctl net.ipv4.tcp_congestion_control=bbr
8重传风暴一次丢包触发多次重传看 RTO 与 dup ACK;Karn 算法不重传 RTT 测量包
9连接迁移失败TCP 靠 4 元组,移动换 IP 就断用 QUIC,看 connection_id 不变继续
10UDP 巨型包被截应用发 64KB,IPv4 链路只让 1500B分片;建议 MTU 不超 1200B,避免 IPv4/IPv6 路径分片
11DNS 抓包看不到响应TCP 53 替代 UDP 53,怀疑劫持抓 TCP;DNS 53 早就支持 TCP
12QUIC 抓包是乱码几乎全部加密看 Initial 包 + CRYPTO 帧;用 Wireshark QUIC 解密密钥

9.5 学习难点

概念难点

难点为什么会卡突破路径
序号 vs 确认号seq 是数据首字节,ack 是期望下一字节抓一个包画箭头:SYN seq=x, ack=0
flags 位多6 位 TCP flags 难记按位算:SYN=0x02, ACK=0x10, FIN=0x01
rwnd vs cwnd两个窗口都管速率,作用不同rwnd 防接收方被淹,cwnd 防网络被淹
TIME_WAIT 2MSL主动关闭方要等 2 个 MSL目的是让对端能收到最后的 ACK
慢启动阈值ssthresh 从哪来第一次丢包时把 cwnd/2 作为 ssthresh
BBR 模型不靠丢包,靠带宽×RTT 估计读 BBR 论文的 BtlBwRTprop 估计

思维难点

难点为什么会卡突破路径
状态机 11 个状态记不住LISTEN → SYN_SENT → SYN_RCVD → ESTABLISHED → FIN_WAIT_1 → FIN_WAIT_2 → CLOSE_WAIT → LAST_ACK → TIME_WAIT → CLOSED
重传与快速重传触发条件不同超时重传:RTO 到;快速重传:3 个 dup ACK
拥塞控制的「避免」拥塞避免 ≠ 流量整形拥塞避免是「接近极限时收敛」,不是「停下来」
队头阻塞TCP 与 HTTP/2 都有TCP 字节流级;HTTP/2 单连接级;QUIC 流级
0-RTT 风险重放攻击0-RTT 只能用于幂等请求

工程难点

难点为什么会卡突破路径
ss -tin 字段多不知道哪个是关键记住 cwndrwndrttretrans 四个
抓包 seq 不变没加 -S 看到的是相对值必加 -S;否则永远是 0/1/2
多网卡混淆-i any 时间戳乱改用具体接口 -i eth0
iperf3 打流慢默认单流,挤不动 BDP增加 -P 4 并发,或加 -w 1M 窗口
算法切换不生效sysctl 改了但内核没加载`lsmod
QUIC 抓包解密TLS 1.3 加密SSLKEYLOGFILE 喂 Wireshark

9.6 技术标准与接口

9.6.1 Entity

名称版本发布组织状态许可证 / 可访问性
TCP (RFC 9293)2022IETF / TSVWG现行标准免费公开
UDP (RFC 768)1980IETF / TSVWG现行标准免费公开
TCP Congestion Control (RFC 5681)2009IETF / TSVWG现行标准免费公开
CUBIC (RFC 9438)2023IETF / TSVWG现行标准免费公开
QUIC (RFC 9000)2021IETF / QUIC WG现行标准免费公开
iperf3持续更新iperf3 项目工具BSD-3-Clause
Linux kernel net stack持续更新Linux Foundation事实标准GPL-2.0

9.6.2 Scope

不适用:实时流媒体裸协议(用 RTP/SRTP)、可靠消息队列(用 QUIC/AMQP)、应用层多路复用(用 HTTP/2、HTTP/3)。

9.6.3 Structure

TCP 头(20 字节,无选项):

偏移字段长度说明
0-1Source Port2 字节
2-3Destination Port2 字节
4-7Sequence Number4 字节当前段首字节
8-11Acknowledgment Number4 字节期望下一字节
12Data Offset + Reserved1 字节头长(4 位)
13Flags1 字节CWR/ECE/URG/ACK/PSH/RST/SYN/FIN
14-15Window Size2 字节rwnd
16-17Checksum2 字节必选
18-19Urgent Pointer2 字节

UDP 头(8 字节):

偏移字段长度
0-1Source Port2 字节
2-3Destination Port2 字节
4-5Length2 字节
6-7Checksum2 字节(IPv4 可选,IPv6 必选)

TCP flags 关键字:

Flag名称用途
SYN同步建立连接
ACK确认确认数据
FIN结束关闭连接
RST复位强制关闭
PSH推送立即交付应用
URG紧急紧急指针有效
CWR/ECE拥塞ECN 反馈

9.6.4 Ecosystem

9.6.5 Depth Tiers

层级名称必须看到什么
L0知道存在知道 TCP 是面向连接可靠字节流;UDP 是无连接;QUIC 是 UDP 上的现代传输
L1看得懂示例看到 ss -tn 的状态列能猜出是连接还是监听
L2能正确调用能用 tcpdump 抓 TCP 三次握手,用 iperf3 打流
L3能解释与排错能解释为啥 TIME_WAIT 多、为啥换 BBR 吞吐涨、为啥 QUIC 抗丢包
L4能设计与扩展能调 sysctl 优化大 RTT 高丢包链路,能看懂 tcp_input.c 与 Linux 算法切换

本计划目标:阶段 9 综合排障时达到 L3

9.6.6 Source

10. 常见误区

11. 所有知识点分类(统一规则)

按本仓库统一分类规则(与父主题一致):

  1. 编程语言
  2. 数据结构与算法
  3. 计算机基础:网络协议、操作系统、组成原理
  4. 工程技术
  5. Web 与后端
  6. 前端与客户端
  7. 数据与人工智能
  8. 项目与职业能力

本计划归属:计算机基础 主 + 工程技术 辅。


直接依赖(1)

查看知识图谱 · 热度 🔥极高