This is a simplified version, so it is rather rough.
package study.netty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; public class EchoServer { private static final Logger LOGGER = LoggerFactory.getLogger(EchoServer.class); private int port; public EchoServer(int port) { this.port = port; } public static void main(String... args) { EchoServer echoServer = new EchoServer (12345); echoServer.start(); } public void start() { NioEventLoopGroup bossGroup = new NioEventLoopGroup(), workerGroup = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .localAddress(port) .childHandler(new ChannelInitializer<Channel>() { @Override protected void initChannel(Channel ch) throws Exception { ch.pipeline().addLast(new EchoServerHandler()); } }); ChannelFuture f = bootstrap.bind().sync(); System.out.println(EchoServer.class.getName() + " started and listen on " + f.channel().localAddress()); f.channel().closeFuture().sync(); } catch (InterruptedException e) { LOGGER.error(e.getMessage()); } finally { try { workerGroup.shutdownGracefully().sync(); bossGroup.shutdownGracefully().sync(); } catch (InterruptedException e) { LOGGER.error(e.getMessage()); } } } }
However, if there is no other reason, it is better to use SimpleChannelInboundHandler. After all, although the performance of the pooled bytebuf is good, it is inevitable to make mistakes in manual maintenance.
package study.netty; import java.nio.charset.StandardCharsets; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; @Sharable public class EchoServerHandler extends ChannelInboundHandlerAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(EchoServerHandler.class); @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { super.channelActive(ctx); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { ByteBuf byteBuf = (ByteBuf) msg; LOGGER.info("echo server receive msg:{}", byteBuf.toString(StandardCharsets.UTF_8)); ctx.write(msg); } @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(); } }
package study.netty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; public class EchoClient { private final Logger logger = LoggerFactory.getLogger(getClass()); private static String host = "127.0.0.1"; private static int port = 12345; public static void main(String[] args) { EchoClient client = new EchoClient(); client.start(); } public void start() { NioEventLoopGroup nelg = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap(); bootstrap.group(nelg) .channel(NioSocketChannel.class) .remoteAddress(host, port) .handler(new ChannelInitializer<Channel>() { @Override protected void initChannel(Channel ch) throws Exception { ch.pipeline().addLast(new EchoClientHandler()); } }); ChannelFuture future = bootstrap.connect().sync(); future.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace (); } finally { try { nelg.shutdownGracefully().sync(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace (); } } } }
package study.netty; import java.nio.charset.StandardCharsets; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> { private final Logger logger = LoggerFactory.getLogger(getClass()); @Override public void channelActive(ChannelHandlerContext ctx) { ctx.writeAndFlush(Unpooled.copiedBuffer("client short msg", StandardCharsets.UTF_8)); } @Override public void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { logger.info("client received:{}", msg.toString(StandardCharsets.UTF_8)); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { logger.error(cause.getMessage()); ctx.close(); } }