尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
C# 工业设备通讯系列(持续更新中...)
文章目录C# 工业设备通讯系列技术博文持续更新...第一篇【C# 工业通讯】封装一个健壮的 TCP Socket 客户端基类心跳与异常处理核心痛点解决方案通用客户端基类设计关键技术点核心代码实现设计要点总结总结C# 工业设备通讯系列技术博文持续更新…系列说明 本系列基于实际工业机械臂控制项目分享 C# 底层 Socket 通讯封装、设计模式应用、高频数据异步读取以及单通道通讯设计的实战经验。第一篇【C# 工业通讯】封装一个健壮的 TCP Socket 客户端基类心跳与异常处理在工业自动化开发中与机械臂、PLC 等设备的 TCP 通讯是基础。本文分享一个基于 C# Socket 封装的通用客户端基类重点解决了连接状态探测Poll、KeepAlive 心跳保活以及异常断开的统一处理。核心痛点在使用原生 Socket 开发工业设备通讯时我们经常遇到以下问题•假连接 socket.Connected 属性并不总是准确的网线被拔了可能还是返回 true。•心跳保活 长时间无数据传输路由器或防火墙可能会切断连接导致对端认为你已离线。•代码复用 每个设备都写一套连接、断开、发送逻辑维护成本高且容易出现遗漏。解决方案通用客户端基类设计我设计了一个抽象类作为底层通讯基类将通用的连接管理逻辑抽离出来子类只需关注具体的业务协议。关键技术点•精准的状态检测 使用 Poll 方法配合 SelectMode.SelectRead 来探测连接是否真实有效。•底层 KeepAlive 通过 IOControl 设置 TCP 层的保活机制防止连接被静默断开。•事件驱动 定义 NetworkErrorEvent将网络异常统一抛给上层处理。核心代码实现usingSystem;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Runtime.InteropServices;usingSystem.Text;namespaceJupiter.Device{/// summary/// 设备客户端基类 - 封装底层 Socket 通讯细节/// 所有机械臂/PLC等设备的通讯类均应继承此类/// /summarypublicabstractclassDeviceClient{privateSocketmSocketClientnewSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);publicstringIP{get;privateset;}publicintPort{get;privateset;}/// summary/// 连接设备入口方法处理重复连接和地址变更/// /summarypublicboolConnect(stringstrIp,intiPort){// 如果已连接且地址未变直接返回避免重复建连if(null!mSocketClientIsConnected()){if(strIp!this.IP||iPort!this.Port){this.Disconnect();}else{returntrue;}}returnthis.ConnectDeviceServer(strIp,iPort);}/// summary/// 真实连接状态检测/// 解决 Connected 属性不准的问题网线拔了可能还是 true/// /summarypublicboolIsConnected(){try{if(mSocketClientnull||!mSocketClient.Connected)returnfalse;// 核心使用 Poll 探测连接状态// 如果 SelectRead 为 true 且 Available 为 0说明连接已被对端关闭boolstateChangedmSocketClient.Poll(1000,SelectMode.SelectRead);if(stateChangedmSocketClient.Available0){returnfalse;}returntrue;}catch(Exceptionex){LogHelper.Error(DeviceClient,ex,连接检测异常);returnfalse;}}/// summary/// 建立物理连接并开启 KeepAlive/// /summaryprivateboolConnectDeviceServer(stringstrIp,intiPort){try{this.IPstrIp;this.PortiPort;mSocketClientnewSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);mSocketClient.Connect(newIPEndPoint(IPAddress.Parse(strIp),iPort));// 【重点】开启 TCP KeepAlive 防止连接被静默断开// 参数说明启用(1) 首次探测时间(5000ms) 探测间隔(500ms)uintdummy0;byte[]optValnewbyte[Marshal.SizeOf(dummy)*3];BitConverter.GetBytes((uint)1).CopyTo(optVal,0);BitConverter.GetBytes((uint)5000).CopyTo(optVal,Marshal.SizeOf(dummy));BitConverter.GetBytes((uint)500).CopyTo(optVal,Marshal.SizeOf(dummy)*2);mSocketClient.IOControl(IOControlCode.KeepAliveValues,optVal,null);OnConnected(mSocketClient);returntrue;}catch(Exceptionex){LogHelper.Error(DeviceClient,ex,连接失败);returnfalse;}}/// summary/// 发送数据UTF-8 文本协议/// /summaryprotectedboolSendData(stringstr){try{byte[]dataEncoding.UTF8.GetBytes(str);return(mSocketClient.Send(data)data.Length);}catch(SocketExceptionex){// 发送失败且连接断开触发网络错误事件if(!IsConnected())NetworkErrorEvent?.Invoke(this,ex.SocketErrorCode);returnfalse;}}/// summary/// 断开连接/// /summarypublicvoidDisconnect(){try{if(mSocketClient!nullmSocketClient.Connected){mSocketClient.Shutdown(SocketShutdown.Both);mSocketClient.Close();}}catch(Exceptionex){LogHelper.Error(DeviceClient,ex,断开连接异常);}finally{OnDisconnected();}}/// summary/// 网络异常事件供上层订阅/// /summarypublicdelegatevoidOnNetworkError(DeviceClientsender,SocketErroriErrCode);publiceventOnNetworkErrorNetworkErrorEvent;// 抽象方法强制子类实现连接成功/断开后的业务逻辑protectedabstractvoidOnConnected(Socketsock);protectedabstractvoidOnDisconnected();}}设计要点总结设计点说明IsConnected() 重写用 Poll Available 替代简单的 Connected 属性判断能准确检测网线拔出等物理断开TCP KeepAlive通过 IOControl 设置底层保活参数首次探测 5s 后开始间隔 500ms有效防止路由器/防火墙切断空闲连接抽象方法隔离OnConnected / OnDisconnected 交由子类实现基类只负责连接生命周期管理事件驱动异常NetworkErrorEvent 让上层决定如何处理异常重试、告警、降级等基类不耦合具体策略总结通过封装这个通用客户端基类我们将繁琐的 Socket 状态管理、字节流转换和异常捕获下沉到了基类。后续开发具体的机械臂控制类时只需要继承它并实现 OnConnected 即可大大提升了代码的可维护性。
RELATED

相关推荐

家里多了个24小时在线的“AI健康师”

家里多了个24小时在线的“AI健康师”

精神障碍患者的居家康复,长期面临服务难到家、需求难响应的困境。传统康复服务高度依赖人工随访与线下值守,受时间、空间限制,无法实现对患者24小时的居家监护与动态服务跟进。患者家属往往独自承担照护压力,而基层工作人员也疲于…

📅 2026/9/21 10:04:50
IPO(Initial Public Offering)

IPO(Initial Public Offering)

IPO(Initial Public Offering) 上市以及股东套现 干实业是真的累 要多累就有多累

📅 2026/10/2 23:35:30
直播课和录播课,对OSSD申请的影响可能比你想的大

直播课和录播课,对OSSD申请的影响可能比你想的大

帮孩子选 OSSD,有一个问题值得先问自己:这家机构的学分课,是真人直播,还是录播回放? 本质差别在证据链 直播课中,教师实时讲解、互动答疑、过程留痕,成绩单背后有完整的授课记录;录播…

📅 2026/10/10 2:26:02
MORE NEWS

更多资讯

📰

江油市电工证培训学历不高怕报不上名?良心建议来了

江油市电工证培训学历不高怕报不上名?良心建议来了 你是不是觉得学历不高就没办法考电工证?别急,这正是我当年遇到的问题,而且我身边很多工友也都是这样。别被这些条条框框吓住了,其实 江油市电工证培训…

📰

江门考电工证补贴通过率揭秘:电工证不拿到手,根本找不到工作

江门考电工证补贴通过率揭秘:电工证不拿到手,根本找不到工作 你是不是正愁找不到工作?是不是看到招聘信息里写着“持有低压电工证优先”“高压电工证必须”?别急,今天就给你讲讲江门考电工证补贴的那些事儿,尤其是怎么提高通过率,别再被坑了。…

📰

罗平电工证过期了不知道怎么复审延期?上岗必备操作全解析

罗平电工证过期了不知道怎么复审延期?上岗必备操作全解析 证书过期了不知道怎么复审延期?这是很多电工从业者最头疼的问题之一。特别是在罗平地区,电工证作为 上岗必备…

📰

深圳优质电工证怎么考不被坑?考前押题攻略全在这

深圳优质电工证怎么考不被坑?考前押题攻略全在这 不知道去哪报名怕被中介坑,这几乎是想考深圳优质电工证的新人第一反应。网上信息五花八门,中介乱收费、证书无效、考试不通过,这些问题都让人头疼。其实,只要你掌握正确流程,避开坑点,考前押题准备充分…

📰

江油市电工证培训官方回应实操考试心里没底怕挂科

江油市电工证培训官方回应实操考试心里没底怕挂科 实操考试心里没底怕挂科,这是很多准备报考江油市电工证培训的学员的真实写照。特别是对于第一次接触特种作业证考试的人来说,面对高压电工证、低压电工证等考试内容,心里总是七上八下的。不过,…

📰

鹏诚考电工证网上查询别走弯路,新手避坑全攻略

鹏诚考电工证网上查询别走弯路,新手避坑全攻略 你是不是也这样, 不知道去哪报名怕被中介坑 ?网上搜“鹏诚考电工证”一搜一大把,信息真假难辨,还容易被各种中介套路。别急,这篇文章就是帮你搞清楚“鹏诚考电工证网上查询”的门道,从报名、考试到证书…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬