You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取已断开连接的socket的对端连接信息?

解决方案

getpeername()返回ENOTCONN是符合POSIX标准的默认行为:TCP连接触发ECONNRESET后,内核会立即将socket状态置为关闭,getpeername()仅支持在ESTABLISHED状态的socket上正常返回对端信息。

以下是不需要大规模修改现有代码、也不用自行维护全量socket映射表的可行方案:

  • 方案1:连接建立时轻量缓存对端信息
    仅需要在connect()(客户端)或accept()(服务端)返回成功的位置,新增一行获取对端信息的逻辑,将数据和socket文件描述符绑定即可,不需要修改现有业务处理流程,侵入性极低。
    Linux环境下可以直接用setsockopt()的自定义扩展参数缓存,或者用fd作为key存入进程内的轻量哈希表,仅在连接创建和销毁时更新即可。
  • 方案2:读取系统proc文件系统获取历史连接信息
    Linux环境下只要socket文件描述符还未被close()释放,哪怕连接已经断开,也可以从/proc/net/tcp(IPv4)或/proc/net/tcp6(IPv6)中拉取到对应对端信息:
    1. 先用fstat()获取当前socket fd对应的inode号:
      struct stat sock_stat;
      if (fstat(sock_fd, &sock_stat) == 0) {
          ino_t sock_inode = sock_stat.st_ino;
      }
      
    2. 遍历/proc/net/tcp的所有条目,匹配inode字段对应的行,转换rem_address(十六进制大端IP)和rem_port(十六进制端口)字段即可得到完整的对端地址。
  • 方案3:临时调试用抓包方案
    如果只是临时排查问题,可以直接用tcpdump过滤对应监听端口/目标端口的所有TCP流量,出现ECONNRESET报错时直接从抓包日志中匹配对应五元组即可,不需要修改任何业务代码。

注意:如果已经对socket执行了close()操作释放了文件描述符,所有方案都无法再获取对应连接的对端信息,获取操作必须在close()调用前执行。

内容的提问来源于stack exchange,提问作者Mark Ransom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 00:54:02