必须用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智研社是一个专注于人工智能领域的综合性平台
相关推荐
coderwei1232 小时前
从OpenAI到Strip:用六大支柱读懂Harness Engineering的生产实践海鸥-w2 小时前
Python(FastAPI)中ORM框架Sqlalchemy的安装及建表爱喝水的鱼丶2 小时前
SAP-ABAP:SAP基础数据校验工具开发系列博客(共5篇)第三篇:SAP接口对接开发:实现数据的实时/批量校验交互真香号2 小时前
记一次生产RocketMQ消息积压消费慢的排查与解决数据库小学妹2 小时前
国产数据库技术成熟度实测:从Oracle兼容到高可用,四个维度评估能不能上生产Wonderful U3 小时前
Python+Django实战|个人博客内容管理系统:搭建轻量化、高自由度的个人动态博客CMS系统JdSnE27zv3 小时前
数据库性能优化三:程序操作优化高洁013 小时前
智能体:你的私人数字助理海鸥-w3 小时前
python(fastapi) 实现更新,新增,删除接口淘矿人3 小时前
DeepSeek V4对决Claude 4.8:AI模型终极横评