modbus协议服务端深度解析-基于jlibmodbus
简介
实现(博文动态更新每个版本可能有误差)
- 配置信息
/** * @description Mobdbus * @author: sry * @date: 2022/6/6 14:17 */ public class MobdbusConfig { public String host = "127.0.0.1"; public boolean keepAlive = true; public int port = 502; }
-
抽象类用来加载配置
package com.cddiot.ems.modbus; import com.cddiot.ems.parameter.MobdbusConfig; import com.intelligt.modbus.jlibmodbus.tcp.TcpParameters; import lombok.extern.slf4j.Slf4j; import java.net.InetAddress; import java.net.UnknownHostException; /** * @description 抽象实现配置加载 * @author: sry * @date: 2022/6/6 14:37 */ @Slf4j public abstract class AbstractTcp { static TcpParameters tcpParameters = new TcpParameters(); static{ // 不用yml的原因: 静态代码块是在jvm加载类时执行,此时yml还没有加载所以无法引用 MobdbusConfig mi = new MobdbusConfig(); // tcp 参数已默认设置,如示例 try { tcpParameters.setHost(InetAddress.getByName(mi.host)); } catch (UnknownHostException e) { log.error(" UnknownHostException :{}", e.getMessage()); } tcpParameters.setKeepAlive(mi.keepAlive); tcpParameters.setPort(mi.port); } }
- 核心实现
package com.cddiot.ems.modbus; import com.intelligt.modbus.jlibmodbus.Modbus; import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException; import com.intelligt.modbus.jlibmodbus.exception.ModbusNumberException; import com.intelligt.modbus.jlibmodbus.exception.ModbusProtocolException; import com.intelligt.modbus.jlibmodbus.master.ModbusMaster; import com.intelligt.modbus.jlibmodbus.master.ModbusMasterFactory; import com.intelligt.modbus.jlibmodbus.msg.ModbusRequestBuilder; import com.intelligt.modbus.jlibmodbus.msg.base.ModbusRequest; import com.intelligt.modbus.jlibmodbus.msg.response.ReadHoldingRegistersResponse; import lombok.extern.slf4j.Slf4j; /* * Copyright (C) 2016 "Invertor" Factory", JSC * All rights reserved * * This file is part of JLibModbus. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Vladislav Y. Kochedykov, software engineer. * email: vladislav.kochedykov@gmail.com */ @Slf4j public class SimpleMasterTCP extends AbstractTcp { static public void main(String[] args) { try { // 如果您想单独设置连接参数 // 你应该使用另一种方法:createModbusMasterTCP(String host, int port, boolean keepAlive); ModbusMaster m = ModbusMasterFactory.createModbusMasterTCP(tcpParameters); Modbus.setAutoIncrementTransactionId(true); // 主机 int slaveId = 1; int offset = 0; // 数量 int quantity = 10; try { // since 1.2.8 if (!m.isConnected()) { m.connect(); } // 同样从 1.2.8.4 开始,您可以创建自己的请求并与主服务器一起处理它 ModbusRequest request = ModbusRequestBuilder.getInstance().buildReadHoldingRegisters(slaveId, offset, quantity); // 只有强转类型的才能获取解析好的数据 ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) m.processRequest(request); // 源码中 ModbusResponse 提供的方法 有继承关系所可以可以用查出 基础的信息 log.info(" ServerAddress: ",response.getServerAddress()); log.info(" ProtocolId: ",response.getProtocolId()); log.info(" TransactionId: ",response.getTransactionId()); log.info(" Function: ",response.getFunction()); log.info(" ExceptionCode: ",response.getModbusExceptionCode()); // 您可以获取包含寄存器值的 int[] 或包含原始字节的 byte[] // getRegisters 过时暂时没有替代方案。源码有误,getByte 可以实现但是没有必要 for (int value : response.getRegisters()) { log.info("Address :{}" + offset++,"Value :{} " + value); } } catch (ModbusProtocolException e) { log.error(" ModbusProtocolException :{}",e.getMessage()); } catch (ModbusNumberException e) { log.error(" ModbusNumberException :{}",e.getMessage()); } catch (ModbusIOException e) { log.error(" ModbusIOException :{}",e.getMessage()); } finally { try { m.disconnect(); } catch (ModbusIOException e) { log.error(" ModbusIOException :{}",e.getMessage()); } } } catch (RuntimeException e) { throw e; } catch (Exception e) { log.error(" Exception :{}",e.getMessage()); } } }
- 源码解析
- 暂无
- 说明
博主真心不容易,觉得有用的点个赞就好。没有写的部分表示没有时间写(会动态更新博文)。
博文代码升级记录
- 服务端案例实现,源码分析,简单封装
本文来自博客园,作者:就沈呗,转载请注明原文链接:https://www.cnblogs.com/ruoyushen/p/16348420.html