Netty网络编程实战指南 (2026年03月27日) Netty简介 Netty是Java生态系统中最流行的NIO客户端服务器框架,它提供了简单、高性能的网络编程抽象。Netty被广泛应用于分布式系统、RPC框架、消息中间件等领域(如Dubbo、gRPC、RocketMQ等)。 核心组件 Channel(通道) Channel是对网络连接的抽象,代表一个到实体的开放连接(如硬件设备、文件、网络套接字)。 EventLoop(事件循环) EventLoop处理Channel的I/O操作,每个EventLoop都有自己的线程,用于处理所有注册到它的Channel的事件。
Netty是Java生态系统中最流行的NIO客户端服务器框架,它提供了简单、高性能的网络编程抽象。Netty被广泛应用于分布式系统、RPC框架、消息中间件等领域(如Dubbo、gRPC、RocketMQ等)。
Channel是对网络连接的抽象,代表一个到实体的开放连接(如硬件设备、文件、网络套接字)。
EventLoop处理Channel的I/O操作,每个EventLoop都有自己的线程,用于处理所有注册到它的Channel的事件。
ChannelPipeline是一个拦截器链,包含一系列ChannelHandler,用于处理入站和出站事件。
ChannelHandler是处理I/O事件的接口,包括ChannelInboundHandler(入站)和ChannelOutboundHandler(出站)。
<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.100.Final</version> </dependency>
public class EchoServer { private final int port; public EchoServer(int port) { this.port = port; } public void start() throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ChannelPipeline p = ch.pipeline(); p.addLast(new EchoServerHandler()); } }); ChannelFuture f = b.bind(port).sync(); System.out.println("EchoServer started on port " + port); f.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { new EchoServer(8080).start(); } } @Sharable public class EchoServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { ByteBuf in = (ByteBuf) msg; System.out.println("Server received: " + in.toString(CharsetUtil.UTF_8)); ctx.write(in); // 写回数据 } @Override public void channelReadComplete(ChannelHandlerContext ctx) { ctx.writeAndFlush(Unpooled.EMPTY_BUFFER) .addListener(ChannelFutureListener.CLOSE); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); } }
public class EchoClient { private final String host; private final int port; public EchoClient(String host, int port) { this.host = host; this.port = port; } public void start() throws Exception { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group) .channel(NioSocketChannel.class) .remoteAddress(new InetSocketAddress(host, port)) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ch.pipeline().addLast(new EchoClientHandler()); } }); ChannelFuture f = b.connect().sync(); Channel channel = f.channel(); // 发送消息 ByteBuf msg = Unpooled.copiedBuffer("Hello Netty!", CharsetUtil.UTF_8); channel.writeAndFlush(msg); channel.closeFuture().sync(); } finally { group.shutdownGracefully(); } } public static void main(String[] args) throws Exception { new EchoClient("localhost", 8080).start(); } } public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> { @Override protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) { System.out.println("Client received: " + msg.toString(CharsetUtil.UTF_8)); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); } }
// 添加StringDecoder和StringEncoder ch.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8)); ch.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8)); ch.pipeline().addLast(new StringHandler()); @Sharable public class StringHandler extends SimpleChannelInboundHandler<String> { @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) { System.out.println("Received: " + msg); ctx.writeAndFlush("Echo: " + msg); } }
// 自定义消息格式:长度(4字节) + 类型(1字节) + 数据 public class Message { private int type; private byte[] data; // getters and setters } // 解码器:字节流转Message对象 public class MessageDecoder extends ByteToMessageDecoder { @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) { if (in.readableBytes() < 5) { return; // 长度不足,等待更多数据 } in.markReaderIndex(); int length = in.readInt(); byte type = in.readByte(); if (in.readableBytes() < length) { in.resetReaderIndex(); return; // 数据不完整,等待更多数据 } byte[] data = new byte[length]; in.readBytes(data); Message msg = new Message(); msg.setType(type); msg.setData(data); out.add(msg); } } // 编码器:Message对象转字节流 public class MessageEncoder extends MessageToByteEncoder<Message> { @Override protected void encode(ChannelHandlerContext ctx, Message msg, ByteBuf out) { byte[] data = msg.getData(); out.writeInt(data.length); out.writeByte(msg.getType()); out.writeBytes(data); } }
// 添加IdleStateHandler ch.pipeline().addLast(new IdleStateHandler(30, 0, 0, TimeUnit.SECONDS)); ch.pipeline().addLast(new HeartbeatHandler()); public class HeartbeatHandler extends ChannelInboundHandlerAdapter { @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { if (evt instanceof IdleStateEvent) { IdleStateEvent event = (IdleStateEvent) evt; if (event.state() == IdleState.READER_IDLE) { System.out.println("Reader idle, closing connection"); ctx.close(); } } } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { if (msg instanceof ByteBuf) { ByteBuf buf = (ByteBuf) msg; if (buf.readableBytes() == 1 && buf.getByte(0) == 0x00) { // 心跳包 ctx.writeAndFlush(Unpooled.copyByte(0x01)); } else { ctx.fireChannelRead(msg); } } } }
// 服务端 ch.pipeline().addLast(new LengthFieldBasedFrameDecoder( 8192, // maxFrameLength 0, // lengthFieldOffset 4, // lengthFieldLength 0, // lengthAdjustment 4 // initialBytesToStrip )); ch.pipeline().addLast(new MessageDecoder()); // 客户端 ch.pipeline().addLast(new LengthFieldPrepender(4)); ch.pipeline().addLast(new MessageEncoder());
ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(EpollServerSocketChannel.class) // Linux使用Epoll .option(ChannelOption.SO_BACKLOG, 1024) .option(ChannelOption.SO_RCVBUF, 32 * 1024) .option(ChannelOption.SO_SNDBUF, 32 * 1024) .childOption(ChannelOption.TCP_NODELAY, true) .childOption(ChannelOption.SO_KEEPALIVE, true) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ch.pipeline() .addLast(new IdleStateHandler(60, 0, 0, TimeUnit.SECONDS)) .addLast(new LengthFieldBasedFrameDecoder(8192, 0, 4, 0, 4)) .addLast(new MessageDecoder()) .addLast(new LengthFieldPrepender(4)) .addLast(new MessageEncoder()) .addLast(new BusinessHandler()); } });
Netty作为高性能网络编程框架,其事件驱动模型和零拷贝技术使其成为Java网络编程的首选。