using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using NModbus; using NModbus.Device; using NModbus.Extensions.Enron; using OpenCvSharp; namespace SmartScanner { class ModbusTCPClient { public TcpClient _client; public IModbusMaster _master; public ModbusFactory factory = new ModbusFactory(); public int isconnnum = 1; public ushort[] previousValus_trigger = { 0, 0 }; //寄存器当前值 public ushort[] currentValus_trigger = { 0, 0 }; //寄存器前一个值 public ushort[] previousValus_ROIModel = { 0, 0 }; public ushort[] currentValus_ROIModel = { 0, 0 }; public bool istrigger = false; // 重连相关字段 public const int MaxReconnectAttempts = 5; // 最大重连次数 public const int ReconnectInterval = 5000; // 重连间隔时间(毫秒) private int _reconnectAttempts = 0; // 当前重连尝试次数 private bool _isReconnecting = false; // 是否正在重连 public void ModbudTCP_Connect(string ipAddress, int port) { try { _client = new TcpClient(ipAddress, port); if (_client.Connected) { // 创建 TCP 客户端 //MessageBox.Show("连接到服务器成功"); // 创建 Modbus 工厂和主机 _master = (ModbusMaster)factory.CreateMaster(_client); if (_master == null) { MessageBox.Show("无法创建 Modbus master 实例。"); return; } // 连接成功,重置重连计数 _reconnectAttempts = 0; } else { if (isconnnum++ < 5) { ModbudTCP_Connect(ipAddress, port); Thread.Sleep(1000); } else { MessageBox.Show("连接到服务器超时"); return; } } } catch (Exception ex) { MessageBox.Show($"连接到服务器失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); Console.WriteLine("连接到服务器失败"); return; } } // 重连方法 public bool Reconnect(string ipAddress, int port) { // 避免重复重连 if (_isReconnecting) return false; _isReconnecting = true; try { // 释放原有连接 _master?.Dispose(); _client?.Close(); _client = null; // 检查是否超过最大重连次数 if (_reconnectAttempts >= MaxReconnectAttempts) { Console.WriteLine("Modbus重连失败,已达到最大重连次数"); return false; } _reconnectAttempts++; Console.WriteLine($"尝试第{_reconnectAttempts}次重连..."); // 尝试重新连接 _client = new TcpClient(); var connectTask = _client.ConnectAsync(ipAddress, port); // 等待连接完成,最多等待5秒 if (connectTask.Wait(5000)) { if (_client.Connected) { _master = (ModbusMaster)factory.CreateMaster(_client); if (_master != null) { // 重连成功,重置计数 _reconnectAttempts = 0; Console.WriteLine("Modbus重连成功"); return true; } } } return false; } catch (Exception ex) { Console.WriteLine($"重连失败: {ex.Message}"); return false; } finally { _isReconnecting = false; } } public ushort[] HoldingRegisterRead(ushort starAddress) //读保持寄存器 { try { ushort[] registerValues = _master.ReadHoldingRegisters(1, starAddress, 1); return registerValues; } catch (Exception ex) { Console.WriteLine($"读取保持寄存器失败: {ex.Message}"); throw; } } public void HoldingRegisterWrite(ushort registerAddress, ushort WriteValue) //写保存寄存器 { try { _master.WriteSingleRegister(1, registerAddress, WriteValue); } catch (Exception ex) { Console.WriteLine($"写入保持寄存器失败: {ex.Message}"); throw; } } public void SingleCoilWrite(ushort CoilAddress, bool valueToWrite) //写单线圈 { try { _master.WriteSingleCoil(1, CoilAddress, valueToWrite); } catch (Exception ex) { Console.WriteLine($"写入单线圈失败: {ex.Message}"); throw; } } public void MultipleRegistersWrite(ushort starAddress, ushort[] valueToWrite) { try { _master.WriteMultipleRegisters(1, starAddress, valueToWrite); } catch (Exception ex) { Console.WriteLine($"写入多个寄存器失败: {ex.Message}"); throw; } } public ushort[] InputRegistersRead(ushort starAddress) { try { ushort[] registerValues = _master.ReadInputRegisters(1, starAddress, 1); return registerValues; } catch (Exception ex) { Console.WriteLine($"读取输入寄存器失败: {ex.Message}"); throw; } } } }