package org.springblade.jfpt.nettyTcpServer; import io.netty.bootstrap.ServerBootstrap; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.ServerSocketChannel; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import io.netty.handler.codec.LengthFieldPrepender; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.logging.LoggingHandler; import java.nio.ByteOrder; import java.nio.charset.Charset; public class TcpServer { private int port; private ServerSocketChannel serverSocketChannel; public TcpServer(int port){ this.port = port; bind(); } private void bind() { Thread thread = new Thread(new Runnable() { @Override public void run() { //服务端要建立两个group,一个负责接收客户端的连接,一个负责处理数据传输 //连接处理group EventLoopGroup boss = new NioEventLoopGroup(); //事件处理group EventLoopGroup worker = new NioEventLoopGroup(); ServerBootstrap bootstrap = new ServerBootstrap(); // 绑定处理group bootstrap.group(boss, worker).channel(NioServerSocketChannel.class) //保持连接数 .option(ChannelOption.SO_BACKLOG, 128) //有数据立即发送 .option(ChannelOption.TCP_NODELAY, true) //保持连接 .childOption(ChannelOption.SO_KEEPALIVE, true) .childOption(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(512*250)) .childHandler(new NettyChannelHandler()); //绑定端口,同步等待成功 ChannelFuture future; try { future = bootstrap.bind(port).sync(); if (future.isSuccess()) { serverSocketChannel = (ServerSocketChannel) future.channel(); System.out.println("服务端启动成功,端口:"+port); } else { System.out.println("服务端启动失败!"); } //等待服务监听端口关闭,就是由于这里会将线程阻塞,导致无法发送信息,所以我这里开了线程 future.channel().closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); } finally { //优雅地退出,释放线程池资源 boss.shutdownGracefully(); worker.shutdownGracefully(); } } }); thread.start(); } private class NettyChannelHandler extends ChannelInitializer { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { //socketChannel.pipeline().addLast(new MyNettyDecode()); //socketChannel.pipeline().addLast(new StringDecoder(Charset.forName("UTF-8"))); //socketChannel.pipeline().addLast("decoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4)); //socketChannel.pipeline().addLast("encoder", new LengthFieldPrepender(4, false)); socketChannel.pipeline().addLast(new TcpServerHandler()); } } }