Commit a80d6ec5 authored by wanghao's avatar wanghao

Revert "1 测试 上电后通信 和 最终完成 定时任务功能"

parent 03b43c92
...@@ -159,46 +159,35 @@ public class DeviceStatusReaderAndTimeSetter { ...@@ -159,46 +159,35 @@ public class DeviceStatusReaderAndTimeSetter {
return master; return master;
} }
/** /**
* 核心修复:反射获取TcpMaster底层Socket(内部类路径正确 * 修正:直接从TcpMaster获取socket字段(适配Modbus4j 3.0.3版本
*/ */
private static Socket getUnderlyingSocket(ModbusMaster master) { private static Socket getUnderlyingSocket(ModbusMaster master) {
if (!(master instanceof TcpMaster)) { if (!(master instanceof TcpMaster)) {
log.error("ModbusMaster类型错误(实际:{}),无法获取Socket", master.getClass().getName()); log.error("ModbusMaster不是TcpMaster类型,无法获取Socket");
return null; return null;
} }
TcpMaster tcpMaster = (TcpMaster) master; TcpMaster tcpMaster = (TcpMaster) master;
try { try {
// 关键:内部类路径必须加 "$"(Modbus4j 3.x/4.x 通用) // 直接获取TcpMaster的private字段 "socket"(你的版本中直接存在该字段)
String transportClassName = "com.serotonin.modbus4j.ip.tcp.TcpMaster$TcpTransport"; Field socketField = TcpMaster.class.getDeclaredField("socket");
Class<?> transportClass = Class.forName(transportClassName); socketField.setAccessible(true); // 取消私有字段访问限制
log.debug("加载TcpMaster内部类成功:{}", transportClassName); Socket socket = (Socket) socketField.get(tcpMaster);
// 获取TcpMaster的private字段 "transport" if (socket != null) {
Field transportField = TcpMaster.class.getDeclaredField("transport"); log.debug("成功获取Socket:IP={}, 端口={}",
transportField.setAccessible(true); socket.getInetAddress(), socket.getPort());
Object transport = transportField.get(tcpMaster); } else {
if (transport == null) { log.debug("TcpMaster的socket字段为null(未建立连接)");
log.error("TcpMaster的transport字段为空(连接未初始化)");
return null;
} }
// 获取内部类的private字段 "socket"(若报错,确认字段名是否为"clientSocket")
Field socketField = transportClass.getDeclaredField("socket");
socketField.setAccessible(true);
Socket socket = (Socket) socketField.get(transport);
log.debug("获取Socket成功:IP={}, 本地端口={}", socket.getInetAddress(), socket.getLocalPort());
return socket; return socket;
} catch (ClassNotFoundException e) {
log.error("=== 反射错误:TcpTransport类未找到!===\n" +
"解决方案:1. 打开Modbus4j源码,确认内部类路径;2. 替换transportClassName为实际路径(如 com.xxx.TcpMaster$TcpTransport)", e);
} catch (NoSuchFieldException e) { } catch (NoSuchFieldException e) {
log.error("=== 反射错误:字段未找到!===\n" + log.error("=== 字段未找到!===\n" +
"解决方案:1. 打开TcpMaster源码,确认transport字段名;2. 打开TcpTransport源码,确认socket字段名(可能为clientSocket)", e); "原因:TcpMaster中不存在socket字段(版本不匹配)\n" +
"解决方案:检查你的TcpMaster源码,确认Socket字段名(当前版本应为'socket')", e);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
log.error("反射访问权限失败(安全管理器拦截)", e); log.error("反射访问权限失败(可能被安全管理器拦截)", e);
} catch (Exception e) { } catch (Exception e) {
log.error("获取Socket异常", e); log.error("获取Socket异常", e);
} }
...@@ -211,16 +200,16 @@ public class DeviceStatusReaderAndTimeSetter { ...@@ -211,16 +200,16 @@ public class DeviceStatusReaderAndTimeSetter {
if (master == null) return; if (master == null) return;
try { try {
// 1. 先关闭底层Socket // 1. 直接获取并关闭TcpMaster的socket字段
Socket socket = getUnderlyingSocket(master); Socket socket = getUnderlyingSocket(master);
if (socket != null && !socket.isClosed()) { if (socket != null && !socket.isClosed()) {
socket.close(); socket.close();
log.debug("设备{}: Socket已关闭", deviceId); log.debug("设备{}: 底层Socket已强制关闭", deviceId);
} }
} catch (Exception e) { } catch (Exception e) {
log.error("设备{}: 关闭Socket异常", deviceId, e); log.error("设备{}: 关闭Socket异常", deviceId, e);
} finally { } finally {
// 2. 再销毁ModbusMaster // 2. 调用自带的destroy()方法,双重保障
try { try {
master.destroy(); master.destroy();
log.debug("设备{}: ModbusMaster已销毁", deviceId); log.debug("设备{}: ModbusMaster已销毁", deviceId);
......
...@@ -118,7 +118,7 @@ public class ModbusResultHandler implements Consumer<DeviceStatusReaderDto> { ...@@ -118,7 +118,7 @@ public class ModbusResultHandler implements Consumer<DeviceStatusReaderDto> {
alarmData.setfAlarmData("天-日期写入失败"); alarmData.setfAlarmData("天-日期写入失败");
alarmDataService.insertTEquipmentAlarmData(alarmData); alarmDataService.insertTEquipmentAlarmData(alarmData);
}else { }else {
palletDeviceBinding.setRecordDate(h + ""); palletDeviceBinding.setRecordDate(d + "");
} }
boolean hResult = Modbus4jUtils.writeRegister(master,deviceId, 7, (short) h); boolean hResult = Modbus4jUtils.writeRegister(master,deviceId, 7, (short) h);
...@@ -130,7 +130,7 @@ public class ModbusResultHandler implements Consumer<DeviceStatusReaderDto> { ...@@ -130,7 +130,7 @@ public class ModbusResultHandler implements Consumer<DeviceStatusReaderDto> {
alarmData.setfAlarmData("时-日期写入失败"); alarmData.setfAlarmData("时-日期写入失败");
alarmDataService.insertTEquipmentAlarmData(alarmData); alarmDataService.insertTEquipmentAlarmData(alarmData);
}else { }else {
palletDeviceBinding.setRecordHour(d + ""); palletDeviceBinding.setRecordHour(h + "");
} }
boolean mmResult = Modbus4jUtils.writeRegister(master,deviceId, 8, (short) mm); boolean mmResult = Modbus4jUtils.writeRegister(master,deviceId, 8, (short) mm);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment