知其然,知其所以然
网络协议原理 2026-10-15

半连接队列与全连接队列:backlog 溢出时发生什么

macOS 的 listen(N) 让全连接队列正好容纳 N 个(上限 somaxconn = 128);队列满时服务端仍回 SYN-ACK,客户端 connect 成功但随后被 RST(与 Linux 丢 SYN 不同);netstat -L 的 qlen/incqlen/maxqlen。

网络协议 TCP 半连接队列 全连接队列 backlog somaxconn netstat 真实验证 动画演示
网络协议原理 2026-10-15

SYN Flood 与 SYN Cookie:防御原理

本机 syncookie = 1;用 netlab 拖慢握手并发起 20000 个并发连接,SYN-ACK 里出现 4243 个只有 MSS + SACK 的精简选项(与 cookie 的特征一致,但本机 netstat 的 TCP 计数全是 0,无法确认);SYN cookie 原理的计算演示。

网络协议 TCP SYN Flood SYN Cookie syncache netlab 真实验证 动画演示
网络协议原理 2026-10-15

序号与确认:字节流如何被编号、累积确认如何工作

逐包验证 TCP 序号 / 确认号:数据段的序号 + 载荷 = 下一个确认号,SYN / FIN 各占 1 个序号;4 MiB 下载 196 个数据段只回 45 个 ACK(累积确认);lo0 上发 4.5 GiB 真的看到序号从 4294960721 回绕到 9757。

网络协议 TCP 序号 确认号 累积确认 序号回绕 真实验证 动画演示
网络协议原理 2026-10-15

超时重传:RTO 的计算与指数退避

用 tcp_info 读 srtt / rttvar / rto:RTT 100 ms 时 rto 从 500 ms 收敛到 307 ms ≈ srtt + 4×rttvar + 200 ms 的 rexmt_slop;lo0 上 RTO 下限 230 ms;30% 丢包下首次重传间隔中位 316 ms,之后 353、437 ms,没有看到逐次翻倍。

网络协议 TCP 重传 RTO srtt rttvar 指数退避 真实验证 动画演示
网络协议原理 2026-10-15

快速重传:三个重复 ACK 的触发

2 MiB 传输 1.5% 丢包里 3 次重传的间隔都是 42 ms(≈ 一个 RTT),是快速重传;单个小包丢了没有后续数据触发重复 ACK,首次重传要等 181~275 ms,是前者的 4~7 倍。

网络协议 TCP 快速重传 重复ACK 尾部丢失 真实验证 动画演示
网络协议原理 2026-10-15

SACK:选择性确认让重传更精确

丢包下接收方的 ACK 带 SACK 块(例子:累积确认号 212317,块 [228649, 244981) 长 16332 字节),72 / 72 条在累积确认号之上;3 个洞发送方 3 / 3 从洞的开头重传整段,没有重发洞之后已到的数据;DSACK 这次没有出现。

网络协议 TCP SACK 选择性确认 DSACK 丢包恢复 真实验证 动画演示
网络协议原理 2026-10-15

滑动窗口与流量控制:接收窗口通告

接收方不读时窗口从 342,976 缩到 15,360 字节、发送方停发,send() 一共收下约接收缓冲区加发送缓冲区(474,460 字节);读速决定发送速率;SO_RCVBUF 小于约 256 KiB 的设置在 macOS 上不生效,吞吐 ≈ 窗口 ÷ RTT;窗口更新一次从 7,688 变成 269,000 字节。

网络协议 TCP 滑动窗口 流量控制 接收窗口 窗口更新 真实验证 动画演示
网络协议原理 2026-10-15

零窗口与窗口探测:接收方处理不过来时

接收窗口缩到 976 字节(小于一次写入)后发送方停发,窗口为 0 后每 5.0 秒发一个 1 字节的探测包(固定间隔,不设上限);接收方一读数据,窗口更新 ACK 0.21 ms 就发出,被阻塞的 send() 在 1.3 ms 内返回。

网络协议 TCP 零窗口 窗口探测 persist 窗口更新 真实验证 动画演示
网络协议原理 2026-10-15

窗口缩放选项:为什么 64 KiB 不够

窗口缩放把 16 位窗口(最大 65535)扩到 2^s 倍:本机 s = 6(最大 4,194,240),example.com s = 13;接收缓冲区 autotune 在约 1 秒内把窗口放大到 4 MiB 上限,往返 100 ms 的吞吐稳定在约 41.8 MB/s ≈ 窗口 ÷ RTT;不缩放时到 example.com 只有 0.27 MB/s。

网络协议 TCP 窗口缩放 接收缓冲区 autotune BDP 真实验证 动画演示
网络协议原理 2026-10-15

拥塞控制 1:慢启动与拥塞避免

初始拥塞窗口 10 个 MSS;慢启动每个 RTT 约翻倍(10 → 190 个 MSS);超时重传使 cwnd 掉到 1 个 MSS,快速恢复降后 / 降前中位数 0.70(CUBIC),拥塞避免阶段每 RTT 只涨 0.4~0.8 个 MSS。

网络协议 TCP 拥塞控制 慢启动 拥塞避免 cwnd CUBIC 真实验证 动画演示
网络协议原理 2026-10-15

拥塞控制 2:Reno、CUBIC、BBR 的行为差异

本机默认 CUBIC(macOS 没有按套接字切换算法的接口);实测 CUBIC 的恢复曲线与公式 W(t) = 0.4·(t − K)³ + W_max 吻合(中位误差 6%);在 100 ms 往返、0.1%~3% 丢包下吞吐是 Reno 公式预测的 1.04~2.73 倍;Reno / CUBIC / BBR 的行为差异用玩具模拟说明思路。

网络协议 TCP 拥塞控制 CUBIC Reno BBR Mathis公式 真实验证 动画演示
网络协议原理 2026-10-15

Nagle 算法与延迟 ACK:40 ms 的由来

实测 Nagle 与延迟 ACK:本机 delayed_ack=3,回环上孤立小包 0.1 ms 就回 ACK,经典 40 ms 冲突没复现;但对 example.com 把 HTTP 请求分两次 write,Nagle 开 403 ms 对 TCP_NODELAY 201 ms,差约一个 RTT;2 万次 100 字节小写入 Nagle 合并成 908 段,NODELAY 是 20000 段。

网络协议 TCP Nagle 延迟ACK TCP_NODELAY 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号