首先引入 Netty 的依赖

<dependency>
     <groupId>io.netty</groupId>
     <artifactId>netty-all</artifactId>
     <version>4.1.36.Final</version>
</dependency>

Server

public class NettyServer { 
    public static void main(String[] args) { 
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workGroup = new NioEventLoopGroup();

        try { 
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            
            serverBootstrap.group(bossGroup,workGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new NettyServerInitailizer())
                    .option(ChannelOption.SO_BACKLOG, 128);

            ChannelFuture channelFuture = serverBootstrap.bind(8000).sync();
            System.out.println("Netty Server started...");

            channelFuture.channel().closeFuture().sync();
        } catch (Exception e){ 
            e.printStackTrace();
        } finally { 
            bossGroup.shutdownGracefully();
            workGroup.shutdownGracefully();
        }
    }

}
public class NettyServerInitailizer extends ChannelInitializer<SocketChannel> { 
    @Override
    protected void initChannel(SocketChannel socketChannel) { 
        ChannelPipeline pipeline = socketChannel.pipeline();
// pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));
// pipeline.addLast(new LengthFieldPrepender(4));
        pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
        pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
        pipeline.addLast(new NettyServerHandler());
    }
}
/** * SimpleChannelInboundHandler 是 ChannelInboundHandlerAdapter 的子类 */
public class NettyServerHandler extends SimpleChannelInboundHandler<String> { 
	
	/** * 有新的客户端连接时触发 * * @param ctx 上下文对象, 含有通道channel,管道pipeline * @throws Exception */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception { 
        System.out.println("新的客户端..." + ctx.channel().remoteAddress());
    }
	
	/** * 读取客户端发送的数据 * * @param ctx 上下文对象, 含有通道channel,管道pipeline * @param msg 就是客户端发送的数据 * @throws Exception */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { 
    	// 注:因为已经引入了编解码器,所以这里直接就是可以读写 String 类型消息,不用再先包装成 ByteBuf
        System.out.println(ctx.channel().remoteAddress() +":" + msg);
        ctx.channel().writeAndFlush("Hello Client --"+ UUID.randomUUID().toString().substring(0,7));
    }
    
    /** * 处理异常, 一般是需要关闭通道 * * @param ctx * @param cause * @throws Exception */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 
        cause.printStackTrace();
        ctx.close();
    }
}

Client

public class NettyClient { 
    public static void main(String[] args){ 
        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
        
        try { 
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(eventLoopGroup)
                    .channel(NioSocketChannel.class)
                    .handler(new NettyClientInitailizer())
					
            ChannelFuture channelFuture = bootstrap.connect("localhost",8000).sync();
            System.out.println("Netty Client started...");

            channelFuture.channel().closeFuture().sync();
        } catch (Exception e){ 
            e.printStackTrace();
        }
        finally { 
            eventLoopGroup.shutdownGracefully();
        }
    }
}
public class NettyClientInitailizer extends ChannelInitializer<SocketChannel> { 
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception { 
        ChannelPipeline pipeline = socketChannel.pipeline();
// pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));
// pipeline.addLast(new LengthFieldPrepender(4));
        pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
        pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
        pipeline.addLast(new NettyClientHandler());
    }
}
public class NettyClientHandler extends SimpleChannelInboundHandler<String> { 
	
	/** * 当客户端连接服务器完成就会触发该方法 * * @param ctx * @throws Exception */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception { 
        System.out.println("成功连接到服务端..." + ctx.channel().remoteAddress());
        // 注:因为已经引入了编解码器,所以这里直接就是可以读写 String 类型消息,不用再先包装成 ByteBuf
        ctx.writeAndFlush("Hello Server!");
    }
	
	/** * 当通道有读取事件时会触发,即服务端发送数据给客户端 * * @param ctx 上下文对象, 含有通道channel,管道pipeline * @param msg 就是客户端发送的数据 * @throws Exception */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { 
        System.out.println("Server:"+ msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 
        cause.printStackTrace();
        ctx.close();
    }
}

先后启动 Server 和 Client,结果如下:

本文地址:https://blog.csdn.net/weixin_43935927/article/details/111993298