赞
踩
用的是netty实现的,通过上位机开放出来的ip和端口采集欧姆龙PLC的数据,该案例只包括连接PLC加握手:
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.20.Final</version>
</dependency>
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>() { @Override protected 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))); } }
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 */ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { //握手 ctx.writeAndFlush(Unpooled.wrappedBuffer(HexStringUtil.hexToByteArray("46494E530000000C00000000000000000000000D"))); } /** * 消息处理 * * @param ctx * @param msg * @throws Exception */ @Override public 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
案例源码:
指令的说明介绍请看这个大佬的:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。