0

0

Go如何检测网络连接是否断开_Go连接状态判断方式

P粉602998670

P粉602998670

发布时间:2026-01-13 15:24:10

|

498人浏览过

|

来源于php中文网

原创

io.EOF 表示对端正常关闭,net.ErrClosed 表示本地已关闭,syscall.ECONNRESET 等才是网络异常中断的真实错误;应使用 errors.Is/errors.As 精准判断,而非字符串匹配。

go如何检测网络连接是否断开_go连接状态判断方式

io.EOF 是对端关闭连接的明确信号,net.ErrClosed 表示本地已调用 conn.Close(),而 syscall.ECONNRESETsyscall.ETIMEDOUT 等底层错误码才是网络异常中断(如断网、防火墙拦截、服务崩溃)的真实指纹——靠字符串匹配 "connection reset""use of closed" 会漏判、误判,且无法跨平台兼容。

读写时如何准确识别连接断开

Go 的网络错误不是“字符串日志”,而是可类型断言的结构化值。关键不是看错误文本,而是用 errors.Iserrors.As 做精准分类:

  • io.EOF:读操作返回此值,说明对端已关闭写方向(如调用了 close()),属于**正常断连**,应退出读循环并清理资源
  • errors.Is(err, net.ErrClosed):写操作返回此值,代表本地连接已被显式关闭,不能再读写
  • *net.OpError:绝大多数异常错误都包装在此类型中。需先 errors.As(err, &netErr) 提取,再判断:
    • netErr.Timeout() → 超时(含 context.DeadlineExceeded
    • netErr.Temporary() → 临时性错误(如 syscall.EAGAIN),可重试
    • errors.Is(netErr.Err, syscall.ECONNRESET) → 连接被对端强制重置(常见于进程 crash 或中间设备切断)
    • errors.Is(netErr.Err, syscall.ENETUNREACH) → 网络不可达(路由失效、网卡 down)

不发数据怎么知道连接还活着?

TCP 层的 KeepAlive 默认间隔长(Linux 通常 2 小时),无法满足应用层快速感知需求。必须在应用层主动探测:

  • 对 MySQL:使用 go-sql-driver/mysqlCheckConnLiveness = true 配置,它会在复用连接前调用底层 syscall.Read 检查套接字状态,遇到 syscall.EAGAIN 视为正常,io.EOF 或其他错误则标记连接失效
  • 对 WebSocket:用 gorilla/websocketSetPongHandler 更新最后活跃时间,并启动 goroutine 定期调用 WriteControl(websocket.PingMessage, ...);若 WriteControl 失败或 ReadMessage 返回 websocket.IsUnexpectedCloseError,即判定断开
  • 通用 TCP 连接:可封装一个非阻塞探测函数,类似 MySQL 驱动的 connCheck,通过 rawConn.Read(...) 尝试读 1 字节,根据 n == 0 && err == nil(EOF)、err == syscall.EAGAIN(正常空闲)、err != nil(异常)三态判断

为什么 net.Dial 成功不代表连接可用?

net.Dial("tcp", addr) 只完成三次握手,返回 nil 错误仅表示连接建立成功,**不保证后续读写一定通**。真实场景中常见问题:

怪兽AI数字人
怪兽AI数字人

数字人短视频创作,数字人直播,实时驱动数字人

下载
  • 连接建立后,中间 NAT/防火墙在空闲超时后单向丢弃包,但 TCP 状态仍显示 ESTABLISHED
  • 服务端进程崩溃,但 FIN 包未发出,客户端 Read 会一直阻塞(除非设了 deadline)
  • 云环境 LB 主动踢掉空闲连接,客户端无感知

因此,任何长连接都必须配合:读写 deadline + 心跳探测 + 错误分类处理。例如设置 conn.SetReadDeadline(time.Now().Add(30 * time.Second)),并在每次 Read 后检查是否是 net.ErrorTimeout() == true

容易踩的坑:跨平台与兼容性盲区

不是所有系统都支持底层 socket 探测:

  • connCheck 在 Linux/macOS 可用 syscall.Read,但在 Windows 或某些容器环境(如部分 musl libc 镜像)会 fallback 到空实现(直接返回 nil),导致心跳失效
  • syscall.ECONNRESET 在 Windows 上对应的是 wsa.WSAECONNRESET,不能直接用 errors.Is(err, syscall.ECONNRESET) 判断,需用 x/sys/windows 中的错误码或统一走 netErr.Timeout()/netErr.Temporary() 分支
  • MySQL 驱动的 ReadTimeout 配置只影响 connCheck 探测阶段,不影响实际查询;若没设,探测可能永久阻塞

最稳妥的做法是:始终设 deadline;优先用 errors.Is 判断标准错误变量;对非标准 syscall 错误,结合 netErr.Op"read"/"write")和 Temporary() 做兜底策略。别信连接“看起来还开着”。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

676

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

320

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

346

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1094

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

357

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

675

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

571

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

414

2024.04.29

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

1

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 1.7万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 787人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号