MangoAutomation / modbus4j

A high-performance and ease-of-use implementation of the Modbus protocol written in Java. Supports ASCII, RTU, TCP, and UDP transports as slave or master, automatic request partitioning and response data type parsing.
GNU General Public License v3.0
897 stars 370 forks source link

请问如何解析16功能码的数据 WriteRegistersRequest 似乎应该暴露 getData 方法 #73

Open 8502596 opened 2 months ago

8502596 commented 2 months ago

image

            ByteQueue b = new ByteQueue("02040000001B01100000000A140101000000000000010100000000000000000000");
            IncomingMessage message = new XaMessageParser(false).parseMessage(b);
            XaMessageRequest request = (XaMessageRequest) message;
            WriteRegistersRequest writeRegistersRequest= (WriteRegistersRequest) request.getModbusRequest();
            StringBuilder sb = new StringBuilder();
            for (byte bt : Arrays.copyOfRange(writeRegistersRequest.getData(),0,writeRegistersRequest.getData().length)) {
                sb.append(String.format("%02X ", bt));
            }
            System.out.println(sb);

image

WriteRegistersRequest 写入保持寄存器 里面有保持寄存器的数据

既然 其他的如 ReadHoldingRegistersResponse ReadInputRegistersResponse 等 返回类中 带有 getData() 而 对应 ReadInputRegistersRequest ReadHoldingRegistersRequest 没有数据 所有没有 getData()

相反 WriteRegistersResponse 返回 本身没有保持寄存器的数据 所有没有 getData() 但 WriteRegistersRequest 本身有保持寄存器的数据 却没有暴露 getDate() 方法 有点不太合理

应用如下 很多时候 我们需要创建一个 TCP server 应用modbus TCP 协议 即可 被动接收数据 如 16功能码 客户端只需不断的

给服务器发送 写入保持寄存器的指令 服务器即可获取数据 甚至服务器不需要回复,但我还没有想好如何构建modbusRespone 使用

modbus4j 而不使用字节拼接,即完成简单的modbus server 关于 16功能码的仿真,有任何人有建议吗?

image

8502596 commented 2 months ago

为了实现 这一点 例如 应用程序 使用 netty server 打开 端口 如 10000 ,客户端 发送 WriteRegistersRequest 写入数据

服务器 netty server 得到数据后发送 WriteRegistersResponse 我使用如下代码 实现了 此效果 但需要将 WriteRegistersResponse 的构造函数 设置为 public

            ByteQueue b = new ByteQueue("02040000001B01100000000A140101000000000000010100000000000000000000");
            IncomingMessage message = new XaMessageParser(false).parseMessage(b);
            XaMessageRequest request = (XaMessageRequest) message;

            StringBuilder sb = new StringBuilder();
            for (byte bt : Arrays.copyOfRange(request.getMessageData(),0,request.getMessageData().length)) {
                sb.append(String.format("%02X ", bt));
            }
            System.out.println("server recived:"+sb);
            WriteRegistersRequest writeRegistersRequest= (WriteRegistersRequest) request.getModbusRequest();
            WriteRegistersResponse writeRegistersResponse=
                    new WriteRegistersResponse(writeRegistersRequest.getSlaveId()
                            , writeRegistersRequest.getStartOffset(), writeRegistersRequest.getData().length/2);

            IpMessageResponse ipMessageResponse=new XaMessageResponse(writeRegistersResponse,request.getTransactionId());

            StringBuilder sb1 = new StringBuilder();
            for (byte bt : Arrays.copyOfRange(ipMessageResponse.getMessageData(),0,ipMessageResponse.getMessageData().length)) {
                sb1.append(String.format("%02X ", bt));
            }
            System.out.println("server reply:"+sb1);

image

我认为 将 修改 WriteRegistersResponse 构造函数是比较合适的 image