《系统架构师成长之路》第 3 期|计算机网络:TCP 三次握手与可靠传输

《系统架构师成长之路》第 3 期|计算机网络:TCP 三次握手与可靠传输

导读 :第 2 期我们用一次 malloc(16) 把内存管理从头看到尾。本期进入计算机网络线:从"为什么 TCP 需要三次握手"出发,推导可靠传输的三大支柱------序号确认、超时重传(RTO 的数学)与滑动窗口,最后画出拥塞控制的 cwnd 曲线。读完你会真正理解:可靠,是拿什么换来的。


一、为什么需要 TCP:可靠不是免费的

IP 层只做"尽力而为"(best-effort):数据报可能丢失、重复、乱序。TCP 要在这条不可靠的管道上,向上层提供字节流式、可靠、有序的传输。可靠性的代价是:头部开销(20 字节)、握手延迟、拥塞控制下的吞吐波动。

一个架构师必须记住的对照:TCP 用"确认-重传"换可靠性,UDP 用"不确认"换实时性。飞控遥测、实时音视频这类容忍少量丢失、不能容忍延迟抖动的场景,往往选 UDP + 应用层自建重传。

二、三次握手:为什么必须是三次

先看时序(如图 3-1 所示):客户端发 SYN, seq=x;服务端回 SYN+ACK, seq=y, ack=x+1;客户端再回 ACK, seq=x+1, ack=y+1,连接建立。

图3-1 TCP 三次握手:①②③ 三次报文交互,双方各维护一套状态机;seq/ack 互相确认对方初始序号。

为什么两次不够?------反证法推导

假设只用两次握手(客户端 SYN,服务端 SYN+ACK,连接即建立)。构造一个真实会发生的时间线:

  1. 客户端发起连接请求 A(seq=x),报文在网络中滞留(比如路由器缓存队列拥塞,超时了)。
  2. 客户端等不到回应,发起连接请求 B(seq=x'),这次正常完成握手,数据传输完毕,连接关闭。
  3. 滞留的旧报文 A 此时才到达服务端 。服务端收到 A,误以为是新的连接请求,回复 SYN+ACK------于是服务端单方面认为连接建立,一直等待客户端发数据。
  4. 但客户端根本没有这个连接(它认为已经关闭),于是服务端资源被白白占用,且一旦收到旧连接的数据还会造成数据错乱。

三次握手如何解决 :服务端在收到 SYN 并回复 SYN+ACK 后,连接并未建立,必须等客户端的第三个 ACK 才进入 ESTABLISHED。旧报文 A 到达时,服务端虽然会回 SYN+ACK,但客户端不会应答(它没有这个连接),服务端超时后自行释放------错误连接建立不起来。

关键推导结论:三次握手让"发起方"掌握最终确认权------只有真正想建连的一端能完成第三次 ACK,滞留的旧请求永远无法"单方面"建立连接。

三次握手的两个工程细节

  • SYN 泛洪(SYN Flood) :攻击者只发 SYN 不回 ACK,让服务端堆积半连接。对策:tcp_syncookies(把连接信息编码进 SYN+ACK 的序号里,不占用半连接队列)。
  • seq 初始值 ISN:RFC 793 建议 ISN 随时间递增(每 4 微秒 +1),防止旧连接的数据段混入新连接。

三、可靠传输支柱一:序号与确认

TCP 把字节流编号,每个字节一个序号。接收方确认连续收到的最后一个字节 :ack = 期望收到的下一个序号。

超时重传 RTO 的数学推导(RFC 6298)

第一步:RTT 采样。 每收到一个 ACK,测量发送到确认的时间差,得到样本 RTT。

第二步:加权平均平滑。 用指数加权移动平均(EWMA)估计"正常"的往返时延:

复制代码
SRTT_new = (1 - α) · SRTT_old + α · RTT_sample

取 α = 1/8。推导技巧:越新的样本权重越大(α 越大对新样本越敏感);α 是 1/8 是因为工程上优先"稳"------网络抖动大时,平滑值不剧烈跳动。

第三步:估计方差。 RTT 本身是波动的,重传超时不能只盯平均值,要给一个"波动裕量"。RFC 6298 用 RTTVAR 近似方差:

复制代码
RTTVAR_new = (1 - β) · RTTVAR_old + β · |RTT_sample - SRTT_old|

取 β = 1/4。这里的技巧是:用一阶差分 |RTT_sample − SRTT_old| 代替真正的方差公式,省掉平方/开方,工程上足够用。

第四步:合成 RTO:

复制代码
RTO = SRTT + 4 · RTTVAR

推导含义:把 RTT 近似看成"均值 ± 4 倍标准差"覆盖的区间------4 倍保证绝大多数正常 ACK 不会误判超时;若真的超时,说明网络状态已变,RTO 按指数退避(×2)。

四、可靠传输支柱二:滑动窗口

光靠"发一个等一个"(停等协议)效率太低:链路往返一次只能发一个报文。TCP 用窗口允许一次性发送窗口内的多个报文,如图 3-2 所示。

图3-2 发送窗口示意:窗口大小 = min(cwnd, rwnd);累计确认 + 窗口滑动是"流水线"效率的关键。

累计确认与快重传

接收方只确认连续收到的字节 ,不必逐段回 ACK。若中间缺了一段,后续到达的段都会触发"重复 ACK"(值等于缺口的期望序号)。发送方连续收到 3 个重复 ACK ,判定该段丢失------不等超时立刻重传,叫快重传。

推导为什么是 3 而不是 1 或 2:个别报文乱序到达(如 4 先到、3 后到)也会产生 1~2 个重复 ACK;用 3 个做阈值,是在"误判丢包"(乱序)与"检测延迟"(超时)之间取的工程折中。

五、可靠传输支柱三:拥塞控制

窗口由两把锁共同决定:接收方通告的 rwnd(流量控制)+ 发送方维护的 cwnd(拥塞控制)。实际发送窗口 = min(cwnd, rwnd)。

cwnd 随时间的变化规律如图 3-3 所示,分四阶段:

图3-3 cwnd 随 RTT 的变化:横轴为 RTT 轮次,纵轴为 cwnd(单位 MSS)。

慢启动:指数增长

连接刚建立,不知道网络容量,从 cwnd=1(个 MSS)开始,每个 RTT 翻倍:

复制代码
第 k 个 RTT 后:cwnd_k = 2^k  (MSS)

推导:每收到一个 ACK,cwnd += 1------因为 ACK 确认了 cwnd 个段,一个 RTT 内全部收到后 cwnd 翻倍。指数增长直到 cwnd >= ssthresh(初始约 16 或 65535 字节)。

拥塞避免:线性增长

超过 ssthresh 后改加法增长,每个 RTT 只 +1 个 MSS:

复制代码
cwnd = cwnd + 1   (每个 RTT)

推导技巧:相比慢启动的"每 ACK +1",这里是"每 RTT +1"------实现上每收到 ACK 只增加 1/cwnd,凑满一个 RTT 才 +1。目的:在接近网络容量时放慢增速,避免瞬间打爆网络。

丢包后:快重传 + 快恢复

检测到 3 个重复 ACK 时:

复制代码
ssthresh = max(cwnd/2, 2)   // 阈值降到一半(推导:保守假设网络容量只剩一半)
cwnd = ssthresh             // 不回到 1,直接降到新阈值,继续线性增长

推导技巧:快恢复相对"超时重传"(cwnd 直接回 1)的改进在于------既然还能收到重复 ACK,说明网络链路仍在工作,没必要清空窗口;只有真正的超时(网络可能彻底拥塞)才 cwnd=1 重新慢启动。

六、架构视角:什么时候不用 TCP

TCP 的可靠是"端到端重传",代价是延迟不可控(最坏情况一个段重传多次、队头阻塞)。因此:

  • 实时遥测/流媒体/游戏:用 UDP,丢包靠应用层补偿(如飞控 MAVLink over UDP、WebRTC);
  • 需要可靠且能容忍延迟:TCP;
  • 既要低延迟又要可靠:QUIC(在 UDP 之上实现类似 TCP 的可靠 + 多路复用,且握手 1-RTT)。

架构决策的本质:在可靠性、延迟、吞吐三者之间显式地做权衡,而不是默认全要。


小结

  1. 三次握手 = 发起方最终确认,防滞留旧 SYN 误建连(反证法推出"两次不够");
  2. 可靠传输 = 序号 + 累计确认 + RTO(EWMA 推导出 RTO = SRTT + 4·RTTVAR)+ 滑动窗口(min(cwnd, rwnd));
  3. 拥塞控制 = 慢启动(指数)/ 拥塞避免(线性)/ 快重传快恢复(阈值减半)三阶段;
  4. 架构权衡:TCP 可靠换延迟,UDP 实时换可靠,QUIC 试图兼得。

思考题

  1. 用反证法证明"四次握手"是多余的(提示:第三次 ACK 后双方都确认了什么?)。
  2. 如果 RTT 采样混入"重传报文的 ACK"(歧义问题),SRTT 会被拉大还是拉小?Karn 算法怎么处理?
  3. 为什么快恢复后 ssthresh 取 cwnd/2 而不是更小?网络容量假设在哪里成立、哪里不成立?

下期预告

第 4 期「HTTP/HTTPS:从一次请求到 TLS 握手」------把第 2 期"一次请求的六层旅程"落到 HTTP 协议层:报文结构、缓存、连接复用,以及 TLS 握手如何用非对称+对称加密保护数据。

参考资料

  1. RFC 793 --- Transmission Control Protocol(TCP 协议原始规范)
  2. RFC 6298 --- Computing TCP's Retransmission Timer(RTO 计算的权威推导)
  3. RFC 5681 --- TCP Congestion Control(慢启动/拥塞避免/快重传/快恢复)
  4. 《TCP/IP 详解 卷 1:协议》(第 17--21 章)
  5. Kurose & Ross《计算机网络:自顶向下方法》第 3 章
  6. TCP 拥塞控制动画演示(Interactive TCP Congestion Control)
相关推荐
YuanDaima20481 小时前
系统架构与数据库理论基础:PostgreSQL 与 pgvector
数据库·人工智能·docker·postgresql·系统架构·产品经理
德迅--文琪1 小时前
新一代智能分布式云接入:应用加速守护 TCP 业务安全与体验
分布式·tcp/ip·安全
KEYSTONE_lucy13 小时前
跨境供应链技术方案:海外仓维修系统架构与海外仓翻新再售流程解析
系统架构
九零HTTP14 小时前
10月21号-CSDN配菜-IP池的5个坑
服务器·数据库·tcp/ip
ITxiaobing202315 小时前
海外广告投放的 IP 定位服务怎么选?一份基于实测数据的选型参考
网络协议·tcp/ip·php
RockHopper202515 小时前
统一目的的分布式智能体 vs 多个独立应用智能体的集成
人工智能·系统架构·智能体·agent 工程
珠海西格电力17 小时前
物联网(IoT)在零碳园区中的关键作用:万物互联与数据采集
大数据·人工智能·物联网·安全·系统架构·能源
KEYSTONE_lucy17 小时前
技术方案:海外仓维修系统架构与退换货维修、海外仓翻新再售流程拆解
系统架构
Chery114019 小时前
DPE5500 SPI以太网协议栈芯片详解:10/100M以太网、硬件TCP/IP与国产替代方案
arm开发·网络协议·tcp/ip