
Netty Modbus Proxy
coding一月 12, 20221mins
Netty Networking
Netty基础H1
请求响应H2
ChannelInboundHandlerAdapter 中调用ChannelHandlerContext 进行write、flush动作,然后经过一些列的OutboundHandler进行处理和转换,最终由ChannelOutboundBuffer 写到pipeline中。
writeH2
ctx.writeAndFlush 是往输出方向的下一个Handler写
ctx.channel().writeAndFlush 是从pipelined的尾部开始写
Netty中ctx.writeAndFlush与ctx.channel().writeAndFlush的区别 - 代码先锋网
Modbus基础H1
Modbus数据报文格式如下
java
/*** Modbus TCP Frame Description* - max. 260 Byte (ADU = 7 Byte MBAP + 253 Byte PDU)* - Length field includes Unit Identifier + PDU** <----------------------------------------------- ADU -------------------------------------------------------->* <---------------------------- MBAP -----------------------------------------><------------- PDU ------------->* +------------------------+---------------------+----------+-----------------++---------------+---------------+* | Transaction Identifier | Protocol Identifier | Length | Unit Identifier || Function Code | Data |* | (2 Byte) | (2 Byte) | (2 Byte) | (1 Byte) || (1 Byte) | (1 - 252 Byte |* +------------------------+---------------------+----------+-----------------++---------------+---------------+* @throws Exception*/
数据帧由MBAP和PDU构成
- MBAP 包含2个字节的事务编号、协议版本号、数据长度(包含后续的Slave 标识的长度以及PDU的长度)、Slave标识
- PDU 2个字节的Function Code和数据区,不同的Function Code对应的对应的数据区稍有不同。
实现H1
java
public class ProxyHandler extends ChannelInboundHandlerAdapter {private TcpMaster tcpMaster;public ProxyHandler(String targetHost, Integer targetPort) throws ModbusInitException {IpParameters ipParameters = new IpParameters();ipParameters.setHost(targetHost);ipParameters.setPort(targetPort);tcpMaster = (TcpMaster) new ModbusFactory().createTcpMaster(ipParameters, (short)1, true);tcpMaster.init();}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {if (msg instanceof ModbusFrame) {ModbusFrame requestFrame = (ModbusFrame) msg;ModbusRequest request = (ModbusRequest) requestFrame.getMessage();ModbusFrame responseFrame = tcpMaster.callModbusMessageSync(request);ModbusHeader header = responseFrame.getHeader();ctx.writeAndFlush(new ModbusFrame(new ModbusHeader(requestFrame.getHeader().getTransactionIdentifier(),header.getProtocolIdentifier(),header.getLength(),header.getUnitIdentifier()),responseFrame.getMessage()));}}}
评论
新的评论
上一篇
Algolia
索引 时间日期 如果根据时间来进行过滤和排序,必须将数据格式化为Unix时间戳(比如 1435735848 ) Faceting Faceting 相当于类别属性,可以用来过滤结果集。 搜索 设置可搜索属性,需要配置 searchableAttributes 匹配 algoli…
下一篇
Gradle Platform
定义BOM Platform可以定义生成BOM文件 启用插件 定义约束,可以包括外部的依赖和项目的内部依赖 参考: https://docs.gradle.org/current/userguide/platforms.html api 以及 implementation im…
