한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

游戏卡顿白皮书 › L8 Socket 与协议

RST 强制关闭导致最后的数据丢失 SO_LINGER, abrupt RST

原因 ID sk-linger · 主责 研发团队·服务器开发

在含图示和实验的完整版中打开此卡片 →

服务器仓促断开连接时,最后发出的提示或存盘完成信号会丢失。

起因 服务器以强制关闭(RST)的方式关闭连接。SO_LINGER 设为 0 秒,或者没读完收到的数据就关闭,都会这样 → 结果 还在发送中的踢人原因和最后的数据被丢弃 → 画面表现 莫名其妙地出现“因未知错误断开连接”

症状
掉线
因素
丢包
谁会遇到
只有我
何时出现
偶尔随机
负责方
主责 研发团队·服务器开发
研发团队要做的事
发送原因后先只关闭发送方向(shutdown),把收到的数据一直读到对方关闭,然后再关闭;避免 SO_LINGER 0 秒。
监控图上
偶发随机尖峰 · 以 RST 结束的连接数
查看位置
看 nstat -az 中 TcpExtTCPAbortOnData(还有待发数据时以 RST 关闭,SO_LINGER 0 秒)、TcpExtTCPAbortOnClose(还有未读数据时关闭)的增量,在断开瞬间的服务器侧抓包中看发出的是 FIN 还是 RST
确认依据
“因未知错误断开连接”的反馈时间点上服务器发出了 RST,AbortOnData、AbortOnClose 增加
排除依据
服务器以 FIN 正常关闭却看不到原因,看客户端的关闭处理
确认手段
运维工具即可确认(无需游戏代码)

出处

  1. closesocket function (winsock.h) Microsoft
    开启 SO_LINGER 并把时间设为 0,会变成立即重置连接的强制关闭,没发出去的数据会丢失
  2. RFC 9293: Transmission Control Protocol (TCP) IETF
    还有收到的数据没读就关闭时,会发送 RST 告知数据丢失
  3. Graceful Shutdown, Linger Options, and Socket Closure Microsoft
    先用 shutdown 只关闭发送,收到对方的关闭通知后再关闭 socket 的顺序
  4. SNMP counter Linux kernel
    TcpExtTCPAbortOnData:因 SO_LINGER 0 秒等原因,还有待发数据时以 RST 关闭;TcpExtTCPAbortOnClose:还有未读数据时关闭而发送 RST

相关原因

同一层:L8 Socket 与协议

其他层中同样导致“掉线”的原因

查看含图示和实验的原卡片