当前位置: 首页 > wzjs >正文

如皋市网站建设电子商务网店运营推广

如皋市网站建设,电子商务网店运营推广,做网站跟app的区别,夜夜做新郎网站C#编写ModbusTcp类库,模拟plc进行本地通信测试 Modbus是一个应用层协议,常用于工业自动化设备之间的通信,主要有两种传输方式:RTU和TCP。 常见的功能码包括读取线圈(01)、读取离散输入(02)、读保持寄存器(03)、读输入寄存器(04)、写单个线圈(05)、写单个寄存器(…

C#编写ModbusTcp类库,模拟plc进行本地通信测试

Modbus是一个应用层协议,常用于工业自动化设备之间的通信,主要有两种传输方式:RTU和TCP。

常见的功能码包括读取线圈(01)、读取离散输入(02)、读保持寄存器(03)、读输入寄存器(04)、写单个线圈(05)、写单个寄存器(06)、写多个线圈(15)、写多个寄存器(16)等。类库需要支持这些基本操作。

一、协议基础:

  • Modbus TCP 使用 TCP/IP 协议,默认端口 ‌502‌。

  • 数据帧格式:事务标识符(2字节) + 协议标识符(2字节) + 长度(2字节) + 单元标识符(1字节) + Modbus PDU(功能码 + 数据)。
    在这里插入图片描述

二、常用功能码‌:

  • 03 功能码‌:读取保持寄存器(Read Holding Registers)。
  • 06 功能码‌:写单个寄存器(Write Single Register)。

三、工具准备‌:

  • Modbus Slave 模拟器‌:如 Modbus Slave ,用于模拟从站设备。下载地址: 模拟器下载地址
  • 配置从站的 IP(如 127.0.0.1)、端口(502)、寄存器地址和初始值。
    在这里插入图片描述

四、C# 实现步骤‌:

  • 使用 TcpClient 建立 TCP 连接。
  • 构造 Modbus 请求报文并发送。
  • 接收响应报文并解析数据。
  • 处理异常和超时。
    在这里插入图片描述

五、代码实现:

  1. 建立数据连接:
/// <summary>
/// 连接
/// </summary>
/// <returns></returns>
protected override Result Connect()
{var result = new Result();socket?.SafeClose();socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);try{//超时时间设置socket.ReceiveTimeout = timeout;socket.SendTimeout = timeout;//连接IAsyncResult connectResult = socket.BeginConnect(ipEndPoint, null, null);//阻塞当前线程           if (!connectResult.AsyncWaitHandle.WaitOne(timeout))throw new TimeoutException("连接超时");socket.EndConnect(connectResult);}catch (Exception ex){socket?.SafeClose();result.IsSucceed = false;result.Err = ex.Message;result.ErrCode = 408;result.Exception = ex;}return result.EndTime();
}

2.断开连接

public static void SafeClose(this Socket socket)
{try{if (socket?.Connected ?? false) socket?.Shutdown(SocketShutdown.Both);//正常关闭连接}catch { }try{socket?.Close();}catch { }
}

3.读取数据

/// <summary>
/// 读取数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
/// <param name="functionCode">功能码</param>
/// <param name="readLength">读取长度</param>
/// <param name="byteFormatting">大小端转换</param>
/// <returns></returns>
public Result<byte[]> Read(string address, byte stationNumber = 1, byte functionCode = 3, ushort readLength = 1, bool byteFormatting = true)
{var result = new Result<byte[]>();if (!socket?.Connected ?? true){var conentResult = Connect();if (!conentResult.IsSucceed){conentResult.Err = $"读取 地址:{address} 站号:{stationNumber} 功能码:{functionCode} 失败。{ conentResult.Err}";return result.SetErrInfo(conentResult);}}try{var chenkHead = GetCheckHead(functionCode);//1 获取命令(组装报文)byte[] command = GetReadCommand(address, stationNumber, functionCode, readLength, chenkHead);result.Requst = string.Join(" ", command.Select(t => t.ToString("X2")));//获取响应报文var sendResult = SendPackageReliable(command);if (!sendResult.IsSucceed){sendResult.Err = $"读取 地址:{address} 站号:{stationNumber} 功能码:{functionCode} 失败。{ sendResult.Err}";return result.SetErrInfo(sendResult).EndTime();}var dataPackage = sendResult.Value;byte[] resultBuffer = new byte[dataPackage.Length - 9];Array.Copy(dataPackage, 9, resultBuffer, 0, resultBuffer.Length);result.Response = string.Join(" ", dataPackage.Select(t => t.ToString("X2")));//4 获取响应报文数据(字节数组形式)             if (byteFormatting)result.Value = resultBuffer.Reverse().ToArray().ByteFormatting(format);elseresult.Value = resultBuffer.Reverse().ToArray();if (chenkHead[0] != dataPackage[0] || chenkHead[1] != dataPackage[1]){result.IsSucceed = false;result.Err = $"读取 地址:{address} 站号:{stationNumber} 功能码:{functionCode} 失败。响应结果校验失败";socket?.SafeClose();}else if (ModbusHelper.VerifyFunctionCode(functionCode, dataPackage[7])){result.IsSucceed = false;result.Err = ModbusHelper.ErrMsg(dataPackage[8]);}}catch (SocketException ex){result.IsSucceed = false;if (ex.SocketErrorCode == SocketError.TimedOut){result.Err = $"读取 地址:{address} 站号:{stationNumber} 功能码:{functionCode} 失败。连接超时";socket?.SafeClose();}else{result.Err = $"读取 地址:{address} 站号:{stationNumber} 功能码:{functionCode} 失败。{ ex.Message}";}}finally{if (isAutoOpen) Dispose();}return result.EndTime();
}/// <summary>
/// 获取随机校验头
/// </summary>
/// <returns></returns>
private byte[] GetCheckHead(int seed)
{var random = new Random(DateTime.Now.Millisecond + seed);return new byte[] { (byte)random.Next(255), (byte)random.Next(255) };
}/// <summary>
/// 获取读取命令
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
/// <param name="functionCode">功能码</param>
/// <param name="length">读取长度</param>
/// <returns></returns>
public byte[] GetReadCommand(string address, byte stationNumber, byte functionCode, ushort length, byte[] check = null)
{var readAddress = ushort.Parse(address?.Trim());if (plcAddresses) readAddress = (ushort)(Convert.ToUInt16(address?.Trim().Substring(1)) - 1);byte[] buffer = new byte[12];buffer[0] = check?[0] ?? 0x19;buffer[1] = check?[1] ?? 0xB2;//Client发出的检验信息buffer[2] = 0x00;buffer[3] = 0x00;//表示tcp/ip 的协议的Modbus的协议buffer[4] = 0x00;buffer[5] = 0x06;//表示的是该字节以后的字节长度buffer[6] = stationNumber;  //站号buffer[7] = functionCode;   //功能码buffer[8] = BitConverter.GetBytes(readAddress)[1];buffer[9] = BitConverter.GetBytes(readAddress)[0];//寄存器地址buffer[10] = BitConverter.GetBytes(length)[1];buffer[11] = BitConverter.GetBytes(length)[0];//表示request 寄存器的长度(寄存器个数)return buffer;
}/// <summary>
/// 发送报文,并获取响应报文(如果网络异常,会自动进行一次重试)
/// TODO 重试机制应改成用户主动设置
/// </summary>
/// <param name="command"></param>
/// <returns></returns>
public Result<byte[]> SendPackageReliable(byte[] command)
{try{var result = SendPackageSingle(command);if (!result.IsSucceed){WarningLog?.Invoke(result.Err, result.Exception);//如果出现异常,则进行一次重试         var conentResult = Connect();if (!conentResult.IsSucceed)return new Result<byte[]>(conentResult);return SendPackageSingle(command);}elsereturn result;}catch (Exception ex){try{WarningLog?.Invoke(ex.Message, ex);//如果出现异常,则进行一次重试                var conentResult = Connect();if (!conentResult.IsSucceed)return new Result<byte[]>(conentResult);return SendPackageSingle(command);}catch (Exception ex2){Result<byte[]> result = new Result<byte[]>();result.IsSucceed = false;result.Err = ex2.Message;result.AddErr2List();return result.EndTime();}}
}

4.其他类型数据读取

 /// <summary>/// 读取Int16类型数据/// </summary>/// <param name="address">寄存器起始地址</param>/// <param name="stationNumber">站号</param>/// <param name="functionCode">功能码</param>/// <returns></returns>public Result<short> ReadInt16(string address, byte stationNumber = 1, byte functionCode = 3){var readResut = Read(address, stationNumber, functionCode);var result = new Result<short>(readResut);if (result.IsSucceed)result.Value = BitConverter.ToInt16(readResut.Value, 0);return result.EndTime();}/// <summary>/// 按位的方式
http://www.dtcms.com/wzjs/465206.html

相关文章:

  • 建设局网站瓯龙建州府3号楼电商网站建设方案
  • 医药网站 备案写手接单平台
  • 网站服务器 2核百度一级代理商
  • 上海专业做网站较好的公司百度的营销策略
  • 政府网站建设工作的通知搜狗广告联盟
  • 网站有后台更新不了外包网络推广公司推广网站
  • 用c语言可以做网站吗优化大师免费下载
  • 用dw做网站优化怎么做
  • 服装网站建设目的作用是什么seo外包公司兴田德润
  • 什么样的网站开发比较吃香开发一个网站需要哪些技术
  • 学校网站的平台用途及建设规划免费推广软件
  • 大气wordpress主题南宁seo公司哪家好
  • 线上商城如何推广上海牛巨仁seo
  • 不锈钢公司网站源码 网站建设 产品3级分类asp源码长沙关键词优化方法
  • 安徽网站建设公司百度搜索优化平台
  • 福建省建设行业企业资质查询网站百度seo关键词点击软件
  • 软件下载网站模板网络舆情分析师
  • 东莞网站建设aj工作室站内免费推广有哪些
  • 成都手机网站建设价格最新的国际新闻
  • c 怎么和网站做交互免费建设个人网站
  • 网站代运营收费怎样在百度打广告
  • 强生公司网站建设原则电商平台有哪些?
  • 做相册的网站百度竞价排名案例分析
  • 做付费下载的网站深圳今天重大事件新闻
  • 中国执行信息公开网信息查询网站seo优化徐州百度网络
  • 专门做酒店自助餐的网站十大推广app平台
  • 昆明网建seo外包多少钱
  • 武汉网站建设服务商深圳华强北最新消息
  • 网站制作和网页制作区别池州网站seo
  • 西安正规网站建设报价新手怎样推销自己的产品