pom.xml
<!--netty5.0-->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>5.0.0.Alpha2</version>
</dependency>
服务端
1.启动类代码:
import com.zwh.entity.ZwhParamSet;
import com.zwh.mapper.ZwhParamSetMapper;
import com.zwh.service.SaveHisDataService;
import com.zwh.util.MyDecoder;
import com.zwh.util.SpringUtil;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Component("applicationStartup")
public class ApplicationStartup implements ApplicationListener<ContextRefreshedEvent>{
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
int port = 8081;
System.out.println("################服务器已启动################");
NioEventLoopGroup pGroup = new NioEventLoopGroup();
NioEventLoopGroup cGroup = new NioEventLoopGroup();
// 2. 创建服务器辅助类
ServerBootstrap b = new ServerBootstrap();
b.group(pGroup, cGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 1024)
// 3.设置缓冲区与发送区大小
.option(ChannelOption.SO_SNDBUF, 32 * 1024).option(ChannelOption.SO_RCVBUF, 32 * 1024)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
sc.pipeline().addLast("decode",new MyDecoder());
sc.pipeline().addLast(new ServerHandler());
}
});
try{
ChannelFuture cf = b.bind(port).sync();
cf.channel().closeFuture().sync();
}catch (Exception e) {
e.printStackTrace();
}finally {
pGroup.shutdownGracefully();
cGroup.shutdownGracefully();
}
}
}
2.数据处理类:
import com.zwh.service.OperService;
import com.zwh.util.ConvertCode;
import com.zwh.util.SpringUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.net.InetSocketAddress;
@Component
public class ServerHandler extends ChannelHandlerAdapter {
Logger logger = LoggerFactory.getLogger(ServerHandler.class);
//接收到连接,创建该连接,也同时下发指令
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
String ip = insocket.getAddress().getHostAddress();
int port = insocket.getPort();
logger.info("ip:"+ip+":创建链接");
System.out.println("客户端链接:" + ip + ":" + port);
/*//String msg = "0103045100129526";
byte[] bufread= ReadWriteData.reademulshortdata(1,3,1105,18);
Runnable task=handermessage(ctx, tools.bytesToHexString(bufread));
executorService.execute(task);*/
}
public Runnable handermessage(final ChannelHandlerContext ctx,final String msg,Integer second){
return new Runnable() {
@Override
public void run() {
while(true) {
try {
writeToClient(msg,ctx);
Thread.sleep(second);
} catch (Exception e) {
//e.printStackTrace();
}
}
}
};
}
//发送信息
private void writeToClient(final String receiveStr, ChannelHandlerContext channel) {
try {
ByteBuf bufff = Unpooled.buffer();//netty需要用ByteBuf传输
bufff.writeBytes(ConvertCode.hexString2Bytes(receiveStr));//对接需要16进制
channel.writeAndFlush(bufff).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
}
});
} catch (Exception e) {
e.printStackTrace();
System.out.println("调用通用writeToClient()异常"+e.getMessage());
}
}
//断开连接
@Override
public void channelInactive(ChannelHandlerContext ctx){
try{
InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
String ip = insocket.getAddress().getHostAddress();
int port = insocket.getPort();
logger.info("ip:"+ip+":断开链接");
System.out.println("客户端断开链接:" + ip + ":" + port);
//业务处理
//删除缓存中stationId
//OperService operService = (OperService)SpringUtil.getBean("operService");
//OperService.ipMap.remove(ip);
}catch (Exception e){
}
}
//接收数据包
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if(null != msg) {
String str = (String) msg;
//业务处理
//OperService operService = (OperService)SpringUtil.getBean("operService");
//InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
//String ip = insocket.getAddress().getHostAddress();
//operService.operData(str,ip,ctx);
}
}
//抛出异常
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
//cause.printStackTrace();
}
}
客户端:
1.创建连接方法
//配置客户端的线程组,客户端只有一个线程组
EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
//放入自己的业务Handler
socketChannel.pipeline().addLast(new TCPClientHandler());
}
});
//发起异步连接操作,同步阻等待结果
ChannelFuture channelFuture = bootstrap.connect(host, port).sync();
//等待客户端链路关闭
channelFuture.channel().closeFuture().sync();
} finally {
//释放NIO线程组
eventLoopGroup.shutdownGracefully();
}
2.数据处理类:
public class XYDHandler extends ChannelInboundHandlerAdapter {
private Logger logger = LoggerFactory.getLogger(XYDHandler.class);
private XYDConnectThread xydConnectThread;
public XYDHandler(XYDConnectThread xydConnectThread) {
this.xydConnectThread = xydConnectThread;
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
logger.error("连接断开,IP端口为:{}", ctx.channel().remoteAddress());
ctx.channel().eventLoop().schedule(() -> {
xydConnectThread.reConnect();
}, 2, TimeUnit.SECONDS);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf byteBuf = Unpooled.copiedBuffer((byte[]) msg);
logger.info("接收到消息为:{}", ByteBufUtil.hexDump(byteBuf));
}