两个连接四元组共用本地地址 192.0.2.1 和端口 40200,但远端端口分别为 18080 和 18081。复用取决于套接字与内核规则。

TIME-WAIT 保护连接实例,不是独占一个端口号

TIME-WAIT 是 TCP 在某些有序关闭之后继续保留的协议状态。它为必要时重发最后确认、完成关闭交换留出时间,也帮助避免早先连接实例的延迟报文被误认成新连接数据。相关身份包含两端地址和端口,不能把一个 TIME-WAIT 条目简单理解成对某个本地端口号的全局锁。连接四元组和单独端口,是不同范围的概念。 TIME-WAIT 保护连接实例。判断身份要看四元组,复用结果取决于套接字路径与内核条件。 坏掉的样子 普通关闭中,首先发起关闭的一端通常在确认对端 FIN 后进入 TIME-WAIT。这一端可能是客户端,也可能是服务器;同时关闭还可能涉及双方。假定 TIME-WAIT 永远属于服务器,会掩盖真正制造连接周转的工作负载。应查看状态及两端四元组,不能从应用角色推断谁先关闭,也不能把客户端保留该状态直接视为异常。 高频连接周转可能限制到某个目的地的新连接,但 TIME-WAIT 数量很大,本身不证明资源耗尽或应用文件描述符泄漏。应用关闭套接字之后,操作系统仍可保留协议状态。源地址、可用端口、目的地多样性、显式绑定、复用选项与内核行为,都会影响实际限制。诊断资源耗尽之前,应同时测量连接失败与状态分布,而不是只盯一个总数。 混淆 TIME-WAIT 和 FIN-WAIT-2 会导致无效调参。Linux 的 tcp_fin_timeout 控制另一种孤立套接字情形,不是通用的 TIME-WAIT 时长开关。关于 tcp_tw_recycle 的旧建议,也不适用于当前 Linux。复用受到协议安全条件约束,其中包含时间戳相关检查;如果不了解真实套接字路径,仅修改一个参数,就可能产生错误的行为预期。 ...

十一月 13, 2026 · 2 分钟 · XB Field Notes
拥塞窗口与接收窗口分别约束未确认数据;另一条 pacing 时间线显示发送间隔。每个发送端选择自己的拥塞策略。

TCP 拥塞控制由每个发送端决定,两端可以使用不同算法

TCP 拥塞控制限制发送端向容量有限、可能被共享的网络注入数据。拥塞窗口约束未确认数据量,采用 pacing 时还会控制发送在时间上的分布。接收端通告窗口施加的是另一类流量控制限制。这些机制相互作用,却描述不同约束,不能笼统合并成一个“发送速度设置”,否则很难判断真正限制当前连接的是哪一部分。 数据量、发送时序与应用供给是不同约束。回读套接字实际控制器,并结合该算法解释反馈。图中文章报告值未在本轮重现。 坏掉的样子 两端不需要选择完全相同的拥塞控制算法。每端负责控制自己发送的流量,因此 Reno 客户端能够与 CUBIC 服务器通信。TCP 建立过程协商传输选项,没有要求双方发送算法名称一致。把不同控制器名称诊断成协议不匹配,会分散注意力,掩盖真正的路由、缓冲或应用故障。算法选择需要按方向和具体套接字理解。 算法是否可用,也是需要核对的运行时事实。配置字符串写了某个控制器,不证明内核支持它或允许调用进程选择它。Linux 的 TCP_CONGESTION 按套接字设置,受可用和允许算法约束。应检查调用结果,并回读实际名称,不能默认请求标签已生效。选择失败与选择成功后性能不合适,属于不同问题,需要不同处理。 丢失恢复不存在适用于所有情况的统一曲线。重传超时、快速恢复、显式拥塞通知和基于模型的估计,会因控制器不同而产生不同响应。丢失可能来自拥塞,也可能来自其他原因,发送端仍须按算法规则作出反应。增加缓冲并不能自动修复持续丢包或等待确认的连接,也不能替代对具体恢复状态和触发信号的检查。 快速验证 将脚本保存为 check-congestion-control.py,准备 Docker 后运行 python3 check-congestion-control.py。一次性环境使用 Python 3.11.16、iproute2 6.1.0 和 nftables 1.0.6,在 Linux 6.12.76 上验证。NET_ADMIN 与 SYS_ADMIN 支持嵌套命名空间。新建 veth 两个方向出口各增加十毫秒延迟,不修改宿主接口或生产流量: ...

十一月 12, 2026 · 2 分钟 · XB Field Notes