必须用SendAsync。同步Send在连接异常时会阻塞线程,异步可避免阻塞并支持超时控制;心跳应答需超时重试+连续失败计数,TCP.Connected不可靠;KeepAlive不能替代应用层心跳;心跳与业务数据须协议分离。心跳包该用 Send 还是 SendAsync?必须用 SendAsync。同步 Send 在连接已断但 TCP 状态未及时回收(如对方突然掉电、NAT 超时)时会卡住线程,甚至阻塞整个心跳定时器。异步发送能避免阻塞,也方便配合 CancellationToken 控制超时。常见错误现象:心跳线程卡死、CPU 占用突增、后续所有消息无法发出但日志里没报错。心跳数据尽量小,推荐固定 1 字节(如 0xFF),避免触发 Nagle 算法延迟务必设置 Socket.SendTimeout = 3000,并捕获 SocketException 中的 ErrorCode == 10054(连接被远程重置)或 10053(软件导致连接中止)不要在 SendAsync 回调里直接重发------需先检查 args.SocketError == SocketError.Success怎么判断"连接还活着"而不是"只是没回包"?单靠发包不等于连通。真实可用的心跳必须有应答 + 超时重试 + 连续失败计数。TCP 层的 Connected 属性几乎没用------它只反映上一次操作是否成功,不是实时状态。使用场景:移动网络切换、WiFi 断连再重连、防火墙静默丢弃 ACK。客户端发心跳后,启动独立 Task.Delay(5000, token) 等待服务端回包;超时即视为异常连续 3 次心跳无响应(非超时,是根本没收到任何数据),才触发断连逻辑服务端收到心跳后必须立刻 Send 一个确认字节(如 0x00),不能攒着或延迟回复禁用 Socket.NoDelay = false(即开启 Nagle),否则小包会被缓冲,心跳响应延迟不可控KeepAlive 选项能不能代替应用层心跳?不能。系统级 KeepAlive(通过 SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true) 启用)只探测链路层是否可达,且默认间隔长达 2 小时,对业务级连接保活毫无意义。 AI智研社 AI智研社是一个专注于人工智能领域的综合性平台
相关推荐
IvanCodes5 小时前
Python 数据处理(十三):JSON、CSV 与数据序列化Patrick在香港6 小时前
Claude 工具调用返回空:8 次失败里只有 1 次状态码不对,其余全带 200Web3&Basketball6 小时前
CRM Agent 后训练实战:3 倍更少错误AIFQuant7 小时前
ETF行情API接入踩坑记:从报错到跑通的七个问题十二同学啊8 小时前
向量数据库:从核心原理到 RAG 与 Java 实战蓝速科技8 小时前
会议室门牌公告通知发布选型与落地指南丨蓝速科技GPU实战笔记9 小时前
云端 Python 开发:JupyterLab 还是 VS Code Remote-SSH?狗狗狗狗狗乐啊9 小时前
搭一个 AI 对话工作台 AChat:从 0 到可用的完整记录(一)白猫不黑10 小时前
Python实现简易Web弱口令爆破与防护方案kuuailetianzi10 小时前
Python初识:定位、优势与发展历程