C#怎么判断网络是否掉线_C#如何实现心跳包检测机制【进阶】
TCP连接真实断开需主动探测Socket.Connected不可靠应结合Socket.Poll()与Available判断或发心跳包并严格超时处理禁用Nagle、启用KeepAlive仅作兜底异步心跳须捕获异常并原子更新状态。判断 TCP 连接是否真的断开不能只看 Socket.ConnectedSocket.Connected 只是缓存上次操作的状态底层连接早已静默断开时它仍可能返回 true。真实掉线往往发生在对方突然断电、NAT 超时、防火墙中断等场景此时本地 socket 不会主动触发 Disconnected 事件或抛异常。必须主动探测要么发数据看是否抛 SocketException带 WSAETIMEDOUT 或 WSAENETRESET要么用 Socket.Poll() Socket.Available 组合试探socket.Poll(1000, SelectMode.SelectRead) 返回 true且 socket.Available 0 → 对端已关闭连接FINsocket.Poll(1000, SelectMode.SelectRead) 返回 true但读取时抛 SocketException错误码 10054→ 连接被重置socket.Poll(1000, SelectMode.SelectError) 返回 true → 底层异常基本可判为断线心跳包不能只发空字节得带业务语义和超时控制纯 Send(new byte[0]) 在某些中间设备如企业级防火墙、云负载均衡上会被直接丢弃更糟的是即使发了对方不响应也不等于断线——可能只是卡在业务逻辑里。真正可用的心跳要满足三点使用固定格式的轻量协议帧例如 0xFF 0x01 表示心跳请求0xFF 0x02 表示响应避免被中间件误判为无效流量客户端发心跳后启动独立计时器比如 System.Threading.Timer超时建议 3× 心跳间隔未收到响应就标记连接异常服务端收到心跳请求必须立即回响应不能排队或延迟且服务端也要对每个连接维护最后心跳时间戳超过阈值如 5× 客户端心跳间隔主动 CloseTcpClient 和 Socket 层做心跳的区别很实际用 TcpClient 封装看似简单但它隐藏了底层 socket 的状态细节TcpClient.Client.Poll() 可用但 TcpClient.GetStream().ReadAsync() 在连接断开时可能长时间挂起受 ReadTimeout 影响而该属性默认为 0 即无限等待。 Tellers AI Tellers是一款自动视频编辑工具可以将文本、文章或故事转换为视频。