← 返回题目列表

TCP RST 是什么?哪些场景会出现 Connection reset?

高频 中等 第 14 / 30 题 更新于 2026/07/30
TCPRSTConnection reset异常关闭

简化版

TCP RST 表示重置连接,语义是“这条连接不能继续用了”。常见场景包括访问未监听端口、应用异常或强制关闭 socket、连接已关闭后又收到数据、防火墙或代理注入 RST。

详细版

RST 和 FIN 的区别是面试重点:

  1. FIN 是优雅关闭,表示本端不再发送数据,但仍可接收对方数据。
  2. RST 是异常终止,表示连接状态无效或不允许继续通信。
  3. 访问一个没有进程监听的 TCP 端口,目标主机通常会回 RST。
  4. 应用设置强制关闭、进程崩溃、连接池误复用坏连接,都可能导致对端看到 Connection reset by peer
  5. 网络设备也可能因为安全策略、空闲超时、连接表失效而发送 RST。

排查时要区分 RST 是谁发的、发生在握手阶段还是数据传输阶段,以及前面是否有超时、半关闭或应用报错。

完整版教学

一、RST 的语义:连接被重置,不是正常告别

TCP 正常关闭用 FIN,因为 FIN 保留半关闭语义:我不发了,但我还可以收。RST 则更强硬,它告诉对端“当前这条连接在我这里不可用,请立即停止使用”。所以 RST 往往和异常、拒绝、状态不一致有关。

FIN: 我这边的数据发完了,你如果还有数据可以继续发
RST: 这条连接作废,不要再按原连接继续通信

举例:客户端连接 10.0.0.1:8080,但服务端没有进程监听 8080。服务端内核没有对应 socket 来承接这个 SYN,就会回 RST,客户端通常表现为连接被拒绝。

记忆钩子:FIN 是有礼貌地关门,RST 是告诉对方“门不存在或票作废了”。

二、握手阶段的 RST:端口未监听和策略拒绝

握手阶段收到 RST,最常见原因是目标端口没有监听。客户端发 SYN,目标主机发现没有对应监听 socket,就直接回 RST。这个现象和丢包不同:丢包通常表现为 SYN 重试和超时,RST 则是明确拒绝。

端口未监听:
Client -- SYN --------------> Server
Client <-- RST -------------- Server

网络丢包:
Client -- SYN --------------> ?
Client -- SYN retry --------> ?
最终 connect timeout

如果有防火墙、负载均衡、安全设备,它们也可能主动返回 RST。排查时要看 RST 包的源 IP、TTL、MAC、路径位置,判断是服务端内核发的还是中间设备发的。

三、传输阶段的 RST:应用异常和连接状态不一致

连接已经建立后也可能 RST。比如服务端进程崩溃、应用强制关闭 socket、读取到协议非法数据后主动断开,客户端继续写数据时就可能收到 RST 或 Connection reset by peer

还有一种常见情况是连接池复用空闲连接。服务端或中间代理已经把连接关掉了,客户端连接池还以为可用,拿出来写请求,结果对端发现连接状态不匹配,返回 RST。

场景典型表现排查重点
进程崩溃多连接同时 reset服务日志、崩溃时间点
强制关闭没有完整 FIN 流程socket 关闭参数、异常处理
连接池坏连接首个请求失败,重试成功空闲超时、keepalive、探活
代理超时固定空闲时间后 resetLB/Nginx/网关超时配置

四、RST 和 SO_LINGER 的关系

应用关闭 socket 时,通常内核会尽量把发送缓冲区中的数据发完,再走 FIN。某些系统上如果设置了特殊的 SO_LINGER 行为,close 可能变成丢弃未发送数据并发送 RST,从而让对端感知为异常关闭。

普通 close:
应用 close -> 内核尽量发送剩余数据 -> FIN

强制 abort:
应用强制关闭 -> 丢弃缓冲区 -> RST

这就是为什么同样是“关闭连接”,对端看到的可能完全不同。面试里不必展开到每个操作系统参数细节,但要知道应用层关闭方式会影响 TCP 报文行为。

五、Connection reset by peer 到底是谁的问题

Connection reset by peer 的字面意思是“对端重置连接”。但它不等于一定是对端业务代码错误,中间代理也可能伪装成对端发 RST,或者本端先违反协议导致对端重置。

排查顺序可以按时间线走:

1. RST 是谁发出的?
2. RST 前是否有 FIN、超时、重传、非法请求?
3. RST 发生在握手、请求发送、响应读取还是空闲复用?
4. 两端应用日志时间点是否对应?
5. 中间代理是否有 idle timeout / reset 策略?

举个数字例子:Nginx upstream keepalive 空闲超时是 60s,客户端连接池保留空闲连接 300s。第 120s 客户端复用旧连接时,上游可能早已释放,出现 reset。修复方向是让客户端空闲连接寿命短于上游。

六、RST 对数据可靠性有什么影响

FIN 关闭前,TCP 会尽量保证已发送数据被对端接收;RST 则可能导致未读数据被丢弃。对应用协议来说,如果请求或响应在中途被 RST 打断,就不能假设对端已经完整处理。

关闭方式是否优雅未读/未发数据应用处理建议
FIN尽量按序交付可按 EOF 处理
RST可能丢弃视为失败,结合幂等重试
超时不确定状态未知查询结果或幂等补偿

这也是接口设计里强调幂等性的原因:客户端发送请求后遇到 RST,可能不知道服务端是否已经处理了请求。

七、常见误区与追问

  • 误区:RST 一定是网络断了。 RST 是明确的 TCP 报文,很多时候说明对端或中间设备主动拒绝或重置。
  • 误区:Connection reset 一定是服务端 bug。 也可能是客户端复用过期连接、发送非法数据,或代理空闲超时。
  • 误区:FIN 和 RST 都只是关闭连接。 FIN 是优雅半关闭,RST 是异常复位,数据语义不同。
  • 追问:连接被拒绝和连接超时怎么区分? 被拒绝常见是收到 RST,超时常见是 SYN 没有得到有效响应。
  • 追问:为什么连接池会导致 RST? 池里连接空闲太久,对端或代理已释放,本端复用时状态不一致。
  • 追问:RST 后请求能不能直接重试? 只有幂等请求或有去重机制时才安全,否则可能造成重复写入。

八、加强记忆

RST 题按“三问”答:它表示连接被重置;它常出现在端口未监听、强制关闭、坏连接复用、代理策略中;排查要先定位谁发 RST,再看发生阶段和前序报文。把 FIN/RST/超时三者区分清楚,基本就能答到面试官想听的位置。