初始化版本

This commit is contained in:
LL
2025-11-14 16:12:32 +08:00
commit ea40f18aa6
326 changed files with 137063 additions and 0 deletions

952
SLC1-N/ModbusTCP_28.cs Normal file
View File

@@ -0,0 +1,952 @@
using NetWorkHelper;
using NetWorkHelper.IModels;
using NetWorkHelper.TCP;
using SLC1_N;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using static System.Net.Mime.MediaTypeNames;
namespace SLC1_N
{
public class ModbusTCP_28 // 28仪器线程类
{
private Thread RunThread; // 线程
public bool[] ArrCoil = new bool[10];
public uint[] ArrRegister = new uint[100];
public OriginClient chxclient;
public string IP; // ip
public bool isthread = true; // 线程标志位
private bool disposed = false; // 添加IDisposable接口
public bool isRunning { get; set; } // 运行标志位
private string CHX4; // 记录站号的4位十六进制
//public bool isReadRegister = false; // 读取寄存器开关标志位
public ModbusTCP_28(int CH)
{
isRunning = false;
CHX4 = CH.ToString("X4");
//Console.WriteLine($"将地址转为4位十六进制: {CHX4}和{CHX4.Substring(2, 2)}01");
// 初始化数组
for (int i = 0; i < ArrCoil.Length; i++)
{
ArrCoil[i] = false;
}
// 初始化数组
for (int i = 0; i < ArrRegister.Length; i++)
{
ArrRegister[i] = 0;
}
chxclient = new OriginClient(CH);
}
// 连接
public void Connect(string ip)
{
try
{
IP = ip;
// 先取消事件订阅
if (chxclient != null)
{
chxclient.OnDataReceived -= Slot_CH1DataReceived;
chxclient.Disconnect();
}
// 新连接
chxclient.Connect("2000", IP, "9999");
chxclient.OnDataReceived += Slot_CH1DataReceived;
}
catch (Exception ex)
{
mxlLog.Instance.Error($"ModbusTCP_28[{CHX4}]重连失败: {ex.Message}");
}
}
// 断开
public void Disconnect()
{
if (chxclient.IsConnect)
{
chxclient.Disconnect();
}
}
/*
* 连接标志位仅检查TCP连接是否建立
* 但Modbus设备可能还未准备好通信设备启动延迟、端口未完全初始化等
* 加点延时
*/
// 启动通信线程
public void Start()
{
if (RunThread == null || !RunThread.IsAlive)
{
isthread = true;
RunThread = new Thread(() =>
{
Thread.Sleep(500); // 首次启动延迟(重要)
run();
});
RunThread.IsBackground = true; // 设为后台线程
RunThread.Start();
}
}
~ModbusTCP_28()
{
Dispose(false);
}
// 通信主循环
private void run()
{
int sleepcount = 2;
while (isthread)
{
try
{
if (chxclient.IsConnect)
{
//Console.WriteLine($"{CHX4}-[读取]主循环 T: {chxclient.IsConnect}");
if (sleepcount > 0) // 防止刚开始连接 不稳定 加延时
{
sleepcount--;
Thread.Sleep(250);
}
Thread.Sleep(250);
readCoil();
Thread.Sleep(250);
readRegister();
}
else
{
//Console.WriteLine($"{CHX4}-[读取]主循环 F: {chxclient.IsConnect}");
isRunning = false;
}
}
catch
{
mxlLog.Instance.Error($"ModbusTCP_28[{CHX4}]-[读取] 异常: {chxclient.IsConnect}");
isRunning = false;
Thread.Sleep(1000);
}
}
}
// 停止方法
public void Stop()
{
isthread = false;
if (RunThread != null && RunThread.IsAlive)
{
RunThread.Join(1000); // 等待线程结束最多1秒
}
}
// 实现IDisposable
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// 释放资源
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
Stop();
Disconnect();
chxclient?.Dispose();
}
disposed = true;
}
}
// 接收函数
private void Slot_CH1DataReceived(string str, int idata)
{
//Console.WriteLine($"{CHX4}-[接收]数据:{str} idata:{idata}");
isRunning = true; // 收到数据才算通讯正常。可以排除ip正确但通道不正确的情况
if (str.Length > 6 && str.Substring(0, 4) == $"{CHX4.Substring(2, 2)}01")
{
ParseCoilResponse(str, ref ArrCoil);
}
else if (str.Length > 6 && str.Substring(0, 4) == $"{CHX4.Substring(2, 2)}03")
{
ParseRegisterResponse(str, ref ArrRegister);
}
}
// 解析线圈状态响应
private void ParseCoilResponse(string response, ref bool[] targetArray)
{
try
{
if (response.Length < 6 || !response.StartsWith($"{CHX4.Substring(2, 2)}01"))
return;
int byteCount = Convert.ToInt32(response.Substring(4, 2), 16); // 提取字节数第3字节
int dataIndex = 6; // 提取线圈数据从第4字节开始
for (int i = 0; i < byteCount; i++)
{
if (dataIndex + 2 > response.Length) break;
byte coilData = Convert.ToByte(response.Substring(dataIndex, 2), 16);
dataIndex += 2;
// 解析每个Bit8个线圈
for (int bit = 0; bit < 8; bit++)
{
int coilIndex = i * 8 + bit; // 计算线圈全局索引
if (coilIndex >= targetArray.Length) break;
targetArray[coilIndex] = (coilData & (1 << bit)) != 0 ? true : false;
}
}
}
catch (Exception ex)
{
Console.WriteLine($"解析线圈状态出错: {ex.Message}");
mxlLog.Instance.Error($"ModbusTCP_28[{CHX4}] 解析线圈状态出错", ex);
}
}
// 解析寄存器响应
private void ParseRegisterResponse(string response, ref uint[] targetArray)
{
try
{
if (response.Length < 250 || !response.StartsWith($"{CHX4.Substring(2, 2)}03")) // 实际正常收到长度254
return;
int dataIndex = 6; // 数据开始位置
int registerIndex = 0;
while (dataIndex + 4 <= response.Length && registerIndex < targetArray.Length)
{
// 每2字节4个十六进制字符表示一个寄存器值
targetArray[registerIndex++] = Convert.ToUInt32(response.Substring(dataIndex, 4), 16);
dataIndex += 4;
}
}
catch (Exception ex)
{
Console.WriteLine($"解析寄存器值出错: {ex.Message}");
mxlLog.Instance.Error($"ModbusTCP_28[{CHX4}] 解析寄存器值出错", ex);
}
}
// 读取线圈
public void readCoil()
{
if (!chxclient.IsConnect)
return;
chxclient?.SendData($"{CHX4.Substring(2, 2)} 01 00 00 00 07"); // 0开始读7个
}
// 读取寄存器
private void readRegister()
{
if (!chxclient.IsConnect)
return;
chxclient?.SendData($"{CHX4.Substring(2, 2)} 03 03 E8 00 3D "); // 读取 1000 - 1061
}
// 读取浮点
public string readFloat(int index) // addr 是十进制地址(如 1013
{
try
{
ushort low = (ushort)ArrRegister[index]; // 低位
ushort high = (ushort)ArrRegister[index + 1]; // 高位
float fdata = TwoUInt16ToFloat(high, low);
return fdata.ToString(); // 返回字符串形式的浮点数
}
catch (Exception ex)
{
mxlLog.Instance.Error($"ModbusTCP_28[{CHX4}] 解析浮点数出错", ex);
}
return "0";
}
// 读取浮点
public string readFloatF2(int index) // addr 是十进制地址(如 1013
{
try
{
ushort low = (ushort)ArrRegister[index]; // 低位
ushort high = (ushort)ArrRegister[index + 1]; // 高位
float fdata = TwoUInt16ToFloat(high, low);
return fdata.ToString("F2"); // 返回字符串形式的浮点数
}
catch (Exception ex)
{
mxlLog.Instance.Error($"ModbusTCP_28[{CHX4}] 解析浮点数出错", ex);
}
return "0";
}
// 写线圈
public void writeCoil(string straddress, bool bdata)
{
if (!chxclient.IsConnect)
return;
try
{
int address = Convert.ToInt32(straddress);
string hexAddress = address.ToString("X4"); // 将地址转为4位十六进制如 "1" → "0001"
if(bdata)
{
chxclient?.SendData($"{CHX4.Substring(2, 2)} 05 00 {hexAddress.Substring(2, 2)} FF 00");
}
else
{
chxclient?.SendData($"{CHX4.Substring(2, 2)} 05 00 {hexAddress.Substring(2, 2)} 00 00");
}
}
catch (Exception ex)
{
MessageBox.Show($"输入错误: {ex.Message}");
mxlLog.Instance.Error($"ModbusTCP_28[{CHX4}] writeCoil输入错误", ex);
}
}
// 写入单个保持寄存器
public void writeRegister(int address, int value)
{
if (!chxclient.IsConnect)
return;
try
{
string hexAddress = address.ToString("X4"); // 将地址转为4位十六进制如 "1" → "0001"
string hexValue = value.ToString("X4");
string message = $"{CHX4.Substring(2, 2)} 06 {hexAddress.Substring(0, 2)} {hexAddress.Substring(2, 2)} {hexValue.Substring(0, 2)} {hexValue.Substring(2, 2)}";
chxclient?.SendData(message);
}
catch (Exception ex)
{
MessageBox.Show($"输入错误: {ex.Message}");
mxlLog.Instance.Error($"ModbusTCP_28[{CHX4}] writeRegister输入错误", ex);
}
}
//// 写入多个保持寄存器功能码16每个int占用2个寄存器32位
//public void writeRegisters(int address, int[] values)
//{
// if (!chxclient.IsConnect || values == null || values.Length == 0)
// return;
// try
// {
// string hexAddress = address.ToString("X4");
// int regCount = values.Length * 2; // 每个int占2个寄存器
// string message = $"{CHX4.Substring(2, 2)} 10 " + // 站号 + 功能码
// $"{hexAddress.Substring(0, 2)} {hexAddress.Substring(2, 2)} " + // 地址
// //$"{(regCount >> 8):X2} {(regCount & 0xFF):X2} " + // 寄存器数量
// $"{(regCount * 2):X2}"; // 字节数
// foreach (int val in values)
// {
// byte[] bytes = BitConverter.GetBytes(val);
// if (BitConverter.IsLittleEndian)
// Array.Reverse(bytes); // 转为大端序
// message += $" {bytes[0]:X2}{bytes[1]:X2}{bytes[2]:X2}{bytes[3]:X2}";
// }
// chxclient.SendData(message);
// }
// catch (Exception ex)
// {
// Console.WriteLine($"写入多寄存器(int)失败: {ex.Message}");
// }
//}
// 修改为写入多个保持寄存器功能码16每个int对应1个寄存器
public void writeRegisters(int address, int[] values)
{
if (!chxclient.IsConnect || values == null || values.Length == 0)
return;
try
{
string hexAddress = address.ToString("X4");
int regCount = values.Length; // 修正每个int对应1个寄存器
int byteCount = regCount * 2;
// 构建报文头
string message = $"{CHX4.Substring(2, 2)} 10 " + // 站号 + 功能码
$"{hexAddress.Substring(0, 2)} {hexAddress.Substring(2, 2)} " + // 地址
$"{(regCount >> 8):X2} {(regCount & 0xFF):X2} " + // 寄存器数量(关键修复!)
$"{byteCount:X2} "; // 字节数
// 添加所有数据
foreach (int val in values)
{
// 将int拆分为两个字节大端序
ushort value = (ushort)val; // 只取低16位
message += $"{(value >> 8):X2} {(value & 0xFF):X2} ";
}
Console.WriteLine($"多个保持寄存器 writeRegisters(): {message}");
chxclient?.SendData(message.Replace(" ", "")); // 移除空格
}
catch (Exception ex)
{
Console.WriteLine($"写入多寄存器失败: {ex.Message}");
mxlLog.Instance.Error($"ModbusTCP_28[{CHX4}] 写入多寄存器失败", ex);
}
}
/*
高16位(1014): 0x4048
低16位(1013): 0xF5C3
完整32位: 0x4048F5C3
*/
// 写入浮点
public void writeFloat(int address, float value)
{
if (!chxclient.IsConnect)
return;
try
{
byte[] floatBytes = BitConverter.GetBytes(value); // float转换为4字节IEEE 754格式
ushort highRegister = BitConverter.ToUInt16(floatBytes, 2); // 高16位
ushort lowRegister = BitConverter.ToUInt16(floatBytes, 0); // 低16位
string hexAddress = address.ToString("X4"); // 4位十六进制地址
string message = string.Format(
"{0} 10 {1} {2} 00 02 04 {3:X2}{4:X2} {5:X2}{6:X2}",
CHX4.Substring(2, 2), // 站号
hexAddress.Substring(0, 2), // 起始地址高字节
hexAddress.Substring(2, 2), // 起始地址低字节
(byte)(lowRegister >> 8), // 低寄存器高字节
(byte)lowRegister, // 低寄存器低字节
(byte)(highRegister >> 8), // 高寄存器高字节
(byte)highRegister // 高寄存器低字节
);
// 4. 自动添加CRC校验假设SendData会自动添加
chxclient?.SendData(message);
//Console.WriteLine($"writeFloat: {message}");
//chxclient.SendData("01 10 03 F7 00 02 04 F5 C3 40 48"); // 数据是3.14 站号1功能101015写两个字节 1015-F5C3 1016-4048
}
catch (Exception ex)
{
MessageBox.Show($"写入浮点数失败: {ex.Message}");
mxlLog.Instance.Error($"ModbusTCP_28[{CHX4}] 写入浮点数失败", ex);
}
}
// 写入多个浮点数功能码16每个float占用2个寄存器32位
public void writeFloats(int address, float[] values)
{
if (!chxclient.IsConnect || values == null || values.Length == 0)
return;
try
{
// 构造报文头
string hexAddress = address.ToString("X4");
int regCount = values.Length * 2; // 每个float占2个寄存器
string message = $"{CHX4.Substring(2, 2)} 10 " + // 站号 + 功能码
$"{hexAddress.Substring(0, 2)} {hexAddress.Substring(2, 2)} " + // 地址
$"{(regCount >> 8):X2} {(regCount & 0xFF):X2} " + // 寄存器数量
$"{(regCount * 2):X2}"; // 字节数
foreach (float val in values)
{
byte[] bytes = BitConverter.GetBytes(val);
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes); // 转为大端序
// 拆分为两个16位寄存器高16位在前
ushort high = BitConverter.ToUInt16(bytes, 0);
ushort low = BitConverter.ToUInt16(bytes, 2);
message += $" {(high >> 8):X2}{(high & 0xFF):X2} {(low >> 8):X2}{(low & 0xFF):X2}";
}
chxclient?.SendData(message); // 假设自动添加CRC
}
catch (Exception ex)
{
Console.WriteLine($"写入多浮点数失败: {ex.Message}");
mxlLog.Instance.Error($"ModbusTCP_28[{CHX4}] 写入多浮点数失败", ex);
}
}
//UInt16转float
public static float TwoUInt16ToFloat(UInt16 high, UInt16 low)
{
Int32 sum = (high << 16) + (low & 0xFFFF);
byte[] bs = BitConverter.GetBytes(sum);
float fs = BitConverter.ToSingle(bs, 0);
return fs;
}
}
public enum _28Addr
{
[Description("参数编号")]
ParameterNumber = 1000, // 03E8
[Description("当前参数名称")]
CurrentParameterName1 = 1001, // 3E9
[Description("当前参数名称")]
CurrentParameterName2 = 1002, // 3EA
[Description("当前参数名称")]
CurrentParameterName3 = 1003, // 3EB
[Description("当前参数名称")]
CurrentParameterName4 = 1004, // 3EC
[Description("当前参数名称")]
CurrentParameterName5 = 1005, // 3ED
[Description("充气时间")]
InflationTime = 1006, // 3EE
[Description("平衡时间")]
BalanceTime = 1007, // 3EF
[Description("检测时间")]
DetectionTime = 1008, // 3F0
[Description("排气时间")]
ExhaustTime = 1009, // 3F1
[Description("解除输出2时间")]
ReleaseOutput2Time = 1010, // 3F2
[Description("延时1")]
Delay1 = 1011, // 3F3
[Description("延时2")]
Delay2 = 1012, // 3F4
[Description("充气压力上限低位")]
InflationPressureUpperLimitLow = 1013, // 3F5
[Description("充气压力上限高位")]
InflationPressureUpperLimitHigh = 1014, // 3F6
[Description("充气压力下限低位")]
InflationPressureLowerLimitLow = 1015, // 3F7
[Description("充气压力下限高位")]
InflationPressureLowerLimitHigh = 1016, // 3F8
[Description("平衡压差上限低位")]
BalancePressureDiffUpperLimitLow = 1017, // 3F9
[Description("平衡压差上限高位")]
BalancePressureDiffUpperLimitHigh = 1018, // 3FA
[Description("平衡压差下限低位")]
BalancePressureDiffLowerLimitLow = 1019, // 3FB
[Description("平衡压差下限高位")]
BalancePressureDiffLowerLimitHigh = 1020, // 3FC
[Description("允许泄漏量上限低位")]
AllowableLeakageUpperLimitLow = 1021, // 3FD
[Description("允许泄漏量上限高位")]
AllowableLeakageUpperLimitHigh = 1022, // 3FE
[Description("允许泄漏量下限低位")]
AllowableLeakageLowerLimitLow = 1023, // 3FF
[Description("允许泄漏量下限高位")]
AllowableLeakageLowerLimitHigh = 1024, // 400
[Description("等效容积低位")]
EquivalentVolumeLow = 1025, // 401
[Description("等效容积高位")]
EquivalentVolumeHigh = 1026, // 402
[Description("压力单位")]
PressureUnit = 1027, // 403
[Description("泄漏量单位")]
LeakageUnit = 1028, // 404
[Description("仪器状态")]
DeviceStatus = 1034, // 40A
[Description("大漏泄漏量低位(平衡压差)")]
LargeLeakageLow = 1035, // 40B
[Description("大漏泄漏量高位(平衡压差)")]
LargeLeakageHigh = 1036, // 40C
[Description("大漏泄漏量单位(压差单位)")]
LargeLeakageUnit = 1037, // 40D
[Description("微漏泄漏量低位(泄漏量)")]
MicroLeakageLow = 1038, // 40E
[Description("微漏泄漏量高位(泄漏量)")]
MicroLeakageHigh = 1039, // 40F
[Description("微漏泄漏量单位(泄漏量)")]
MicroLeakageUnit = 1040, // 410
[Description("测试结果")]
TestResult = 1041, // 411
[Description("后台压力低位")]
BackgroundPressureLow = 1048, // 418
[Description("后台压力高位")]
BackgroundPressureHigh = 1049, // 419
[Description("后台压差低位")]
BackgroundPressureDiffLow = 1050, // 41A
[Description("后台压差高位")]
BackgroundPressureDiffHigh = 1051, // 41B
[Description("记录-测试压力低位")]
RecordTestPressureLow = 1057, // 421
[Description("记录-测试压力高位")]
RecordTestPressureHigh = 1058, // 422
[Description("记录-压力单位")]
RecordPressureUnit1 = 1059, // 423
[Description("记录-压力单位")]
RecordPressureUnit2 = 1060, // 424
[Description("记录-压力单位")]
RecordPressureUnit3 = 1061, // 0425
// 下面地址无法读取
[Description("记录-测试泄漏量低位")]
RecordTestLeakageLow = 1062, // 426
[Description("记录-测试泄漏量高位")]
RecordTestLeakageHigh = 1063, // 427
[Description("记录-泄漏量单位")]
RecordLeakageUnit1 = 1064, // 428
[Description("记录-泄漏量单位")]
RecordLeakageUnit2 = 1065, // 429
[Description("记录-泄漏量单位")]
RecordLeakageUnit3 = 1066, // 42A
[Description("记录-泄漏量单位")]
RecordLeakageUnit4 = 1067 // 42B
}
// 原FrmClient类
#region FrmClient类
public class OriginClient
{
private SocketState _connectState { get; set; }// 连接状态
private ITcpClient _client { get; set; }// 连接对象
private System.Timers.Timer _timer { get; set; } // 定时器
public bool IsConnect { get; private set; } = false;// 连接状态标志
public int ChannelId { get; private set; }// 通道标识
public event Action<string, int> OnDataReceived;// 数据接收事件
public event Action<bool, int> OnConnectionStateChanged;// 连接状态变化事件
/// <summary>
/// 初始化客户端
/// </summary>
/// <param name="channelId">通道标识</param>
public OriginClient(int channelId)
{
ChannelId = channelId;
InitializeClient();
}
private void InitializeClient()
{
_client = new ITcpClient
{
IsReconnection = true
};
_client.OnStateInfo += Client_OnStateInfo;
_client.OnRecevice += Client_OnRecevice;
_client.OnErrorMsg += Client_OnErrorMsg;
}
/// <summary>
/// 将字符串转换为十六进制字节数组
/// </summary>
private static byte[] StrtoHexbyte(string hexstring)
{
int i;
hexstring = hexstring.Replace(" ", "");
if ((hexstring.Length % 2) != 0)
{
byte[] returnbytes = new byte[(hexstring.Length + 1) / 2];
for (i = 0; i < (hexstring.Length - 1) / 2; i++)
{
returnbytes[i] = Convert.ToByte(hexstring.Substring(i * 2, 2), 16);
}
returnbytes[returnbytes.Length - 1] = Convert.ToByte(hexstring.Substring(hexstring.Length - 1, 1).PadLeft(2, '0'), 16);
return returnbytes;
}
else
{
byte[] returnBytes = new byte[hexstring.Length / 2];
for (i = 0; i < returnBytes.Length; i++)
{
returnBytes[i] = Convert.ToByte(hexstring.Substring(i * 2, 2), 16);
}
return returnBytes;
}
}
/// <summary>
/// 计算CRC冗余码
/// </summary>
private int Crc16_Modbus(byte[] modbusdata, int length)
{
int i, j;
int crc = 0xffff; // 0xffff or 0
for (i = 0; i < length; i++)
{
crc ^= modbusdata[i] & 0xff;
for (j = 0; j < 8; j++)
{
if ((crc & 0x01) == 1)
{
crc = (crc >> 1) ^ 0xa001;
}
else
{
crc >>= 1;
}
}
}
return crc;
}
/// <summary>
/// 连接服务器
/// connectinterval:心跳包发送间隔 0不发
/// </summary>
public void Connect(string connectinterval, string ipaddress, string port)
{
try
{
if (!_client.IsStart)
{
_client.IsReconnection = true;
int interval = int.Parse(connectinterval);
_timer = new System.Timers.Timer
{
Interval = 1000 * interval
};
_timer.Elapsed += Timer_Elapsed;
_timer.Start();
_client.ServerIp = ipaddress;
_client.ServerPort = int.Parse(port);
_client.StartConnect();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
MessageBox.Show(ex.StackTrace);
Disconnect();
throw;
}
}
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
// 可以在这里实现定时发送逻辑
}
/// <summary>
/// 连接错误处理
/// </summary>
private void Client_OnErrorMsg(object sender, NetWorkHelper.ICommond.TcpClientErrorEventArgs e)
{
IsConnect = false;
OnConnectionStateChanged?.Invoke(IsConnect, ChannelId);
}
/// <summary>
/// 接收数据处理
/// </summary>
private void Client_OnRecevice(object sender, NetWorkHelper.ICommond.TcpClientReceviceEventArgs e)
{
var len = e.Data.Length;
if (len > 0)
{
string returnStr = "";
for (int i = 0; i < len; i++)
{
returnStr += e.Data[i].ToString("X2");
}
var message = returnStr;
string value = message.Replace(" ", "");
OnDataReceived?.Invoke(message, ChannelId);
}
}
/// <summary>
/// 连接状态处理
/// </summary>
private void Client_OnStateInfo(object sender, NetWorkHelper.ICommond.TcpClientStateEventArgs e)
{
_connectState = e.State;
if (e.StateInfo.Contains("已断开服务器连接"))
{
Disconnect();
}
else if (e.StateInfo.Contains("已连接"))
{
IsConnect = true;
OnConnectionStateChanged?.Invoke(IsConnect, ChannelId);
}
else
{
IsConnect = false;
OnConnectionStateChanged?.Invoke(IsConnect, ChannelId);
}
}
object sendLock = new object();
/// <summary>
/// 发送数据
/// </summary>
public void SendData(string sendMsg)
{
if (!string.IsNullOrWhiteSpace(sendMsg) && IsConnect)
{
try
{
byte[] byt = StrtoHexbyte(sendMsg);
int str2 = Crc16_Modbus(byt, byt.Length);
string str3 = Convert.ToString((str2 >> 8) & 0xff, 16);
string str4 = Convert.ToString(str2 & 0xff, 16);
if (str3.Length == 1)
{
str3 = "0" + str3;
}
if (str4.Length == 1)
{
str4 = "0" + str4;
}
sendMsg = sendMsg + str4 + str3;
var message = StrtoHexbyte(sendMsg);
if (_client != null)
{
lock (sendLock)
{
_client?.SendData(message);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
MessageBox.Show(ex.StackTrace);
throw;
}
}
}
/// <summary>
/// 断开连接
/// </summary>
public void Disconnect()
{
if (_timer != null)
{
_timer.Stop();
_timer.Dispose();
_timer = null;
}
if (_client != null)
{
_client.IsReconnection = false;
_client.StopConnect();
_client.Dispose();
}
IsConnect = false;
OnConnectionStateChanged?.Invoke(IsConnect, ChannelId);
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
Disconnect();
}
}
#endregion
}