Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
Z
zhmes-agecal
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
耿迪迪
zhmes-agecal
Commits
a80d6ec5
Commit
a80d6ec5
authored
Sep 24, 2025
by
wanghao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "1 测试 上电后通信 和 最终完成 定时任务功能"
parent
03b43c92
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
21 additions
and
32 deletions
+21
-32
DeviceStatusReaderAndTimeSetter.java
...stem/modbus/business/DeviceStatusReaderAndTimeSetter.java
+19
-30
ModbusResultHandler.java
...com/zehong/system/modbus/handler/ModbusResultHandler.java
+2
-2
No files found.
zhmes-agecal-system/src/main/java/com/zehong/system/modbus/business/DeviceStatusReaderAndTimeSetter.java
View file @
a80d6ec5
...
@@ -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
);
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/modbus/handler/ModbusResultHandler.java
View file @
a80d6ec5
...
@@ -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
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment