Java实现欧姆龙FinsTCP协议(推荐用springboot)
依赖
用的是netty实现的,通过上位机开放出来的ip和端口采集欧姆龙PLC的数据,该案例只包括连接PLC加握手:
<dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.20.Final</version></dependency>
FinsTCP协议配置FinsClientConfig
import com.global.common.hex.HexStringUtil;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;/*** Fins协议配置** @author Administrator* @since 1.0.0*/
public class FinsClientConfig {public static ChannelFuture channelFuture;public static void finsStart(String ip, int port) throws Exception {NioEventLoopGroup eventExecutors = new NioEventLoopGroup();try {//创建bootstrap对象,配置参数Bootstrap bootstrap = new Bootstrap();//设置线程组bootstrap.group(eventExecutors)//设置客户端的通道实现类型.channel(NioSocketChannel.class)//使用匿名内部类初始化通道.handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {//添加客户端通道的处理器ch.pipeline().addLast(new MyClientHandler());}});System.out.println("客户端准备就绪,随时可以起飞~");//连接服务端channelFuture = bootstrap.connect(ip, port).sync();//对通道关闭进行监听channelFuture.channel().closeFuture().sync();} finally {//关闭线程组eventExecutors.shutdownGracefully();}}/*** 发送数据** @param msg 数据*/public static void send(String msg) {channelFuture.channel().writeAndFlush(Unpooled.wrappedBuffer(HexStringUtil.hexToByteArray(msg)));}
}
Handler类MyClientHandler
import cn.hutool.core.util.HexUtil;
import com.global.common.hex.HexStringUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;/*** 业务处理** @author Administrator* @since 1.0.0*/
public class MyClientHandler extends ChannelInboundHandlerAdapter {/*** 握手** @param ctx* @throws Exception*/@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {//握手ctx.writeAndFlush(Unpooled.wrappedBuffer(HexStringUtil.hexToByteArray("46494E530000000C00000000000000000000000D")));}/*** 消息处理** @param ctx* @param msg* @throws Exception*/@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {//接收服务端发送过来的消息ByteBuf byteBuf = (ByteBuf) msg;byte[] bytes = ByteBufUtil.getBytes(byteBuf);System.err.println(HexUtil.encodeHexStr(bytes));}
}
下面这个方法可以自己去写一个,比如hutool的HexUtil工具类里就有我这边自己写
/*** 16进制字符串转化为byte数组** @param inHex 要转16进制字节流数组的16进制字符* @return 16进制字节流*/public static byte[] hexToByteArray(String inHex) {int hexlen = inHex.length();byte[] result;if (hexlen % 2 == 1) {// 奇数hexlen++;result = new byte[(hexlen / 2)];inHex = "0" + inHex;} else {// 偶数result = new byte[(hexlen / 2)];}int j = 0;for (int i = 0; i < hexlen; i += 2) {result[j] = hexToByte(inHex.substring(i, i + 2));j++;}return result;}private static byte hexToByte(String inHex) {return (byte) Integer.parseInt(inHex, 16);}
总结:
FinsTCP协议走的还是网络通讯,那还是TCP/IP通讯,只是第一次发送必须是握手报文,然后发送读取数据报文
Java的网络通讯框架我这边比较常用的就是 t-io 以及netty
案例源码:
fins_demo
指令的说明介绍请看这个大佬的:
指令介绍
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
