Backend Development 25 min read

Understanding Netty: Core Components, Architecture, and a Simple Chat Server Example

This tutorial explains why Netty is preferred over raw NIO, introduces its core components and architecture, and walks through a complete Java example of a simple Netty chat server, including handling of connections, message broadcasting, pipeline configuration, and TCP sticky‑packet issues.

Wukong Talks Architecture
Wukong Talks Architecture
Wukong Talks Architecture
Understanding Netty: Core Components, Architecture, and a Simple Chat Server Example

In this article the author revisits Netty after a previous NIO discussion, explaining why Netty is preferred and providing a complete walkthrough of a simple chat server implementation.

It starts with a full Java source of a NettyChatServer, highlighting the use of EventLoopGroup , ServerBootstrap , ChannelInitializer , and custom handlers ( ChatNettyHandler , ChatHolder ) to manage connections, message broadcasting, and user join/quit logic.

The core Netty components are then described: Bootstrap & ServerBootstrap , EventLoopGroup & EventLoop , ByteBuf (pooled vs unpooled, heap vs direct), Channel and its subclasses ( NioServerSocketChannel , NioSocketChannel ), ChannelHandler (inbound/outbound), ChannelPipeline , and ChannelHandlerContext , including how they are linked and how to modify the pipeline.

Special attention is given to TCP sticky‑packet issues (packet fragmentation and aggregation) and how Netty provides decoders such as FixedLengthFrameDecoder , DelimiterBasedFrameDecoder , and LengthFieldBasedFrameDecoder to solve them, with a concrete delimiter‑based echo server example:

public class DelimiterEchoServer {
    public static final String DELIMITER_SYMBOL = "@~";
    public static final int PORT = 9997;
    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(group)
             .channel(NioServerSocketChannel.class)
             .localAddress(new InetSocketAddress(PORT))
             .childHandler(new ChannelInitializer
() {
                 @Override
                 protected void initChannel(Channel ch) throws Exception {
                     ByteBuf delimiter = Unpooled.copiedBuffer(DELIMITER_SYMBOL.getBytes());
                     ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, delimiter));
                     ch.pipeline().addLast(new DelimiterServerHandler());
                 }
             });
            ChannelFuture f = b.bind().sync();
            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully().sync();
        }
    }
}

Finally the article outlines the step‑by‑step server bootstrap process, from creating EventLoopGroups to binding the port and shutting down gracefully, and concludes with references to Netty books, online courses, and open‑source repositories.

backendJavanettyTCPNetwork ProgrammingByteBufChannelPipeline
Wukong Talks Architecture
Written by

Wukong Talks Architecture

Explaining distributed systems and architecture through stories. Author of the "JVM Performance Tuning in Practice" column, open-source author of "Spring Cloud in Practice PassJava", and independently developed a PMP practice quiz mini-program.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.