客户端
package com.geekymv.netty.echo.client; import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; /** * The client's role includes the following tasks: * 1.Connect to the server * 2.Writes data * 3.Waits for and receives the exact same data back from server * 4.Closes the connection */ 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); b.channel(NioSocketChannel.class); // Specify ChannelHandler, using ChannelInitializer, // called once connection established and channel created. b.handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new EchoClientHandler()); } }); ChannelFuture f = b.connect(this.host, this.port).sync(); f.channel().closeFuture().sync(); }finally { group.shutdownGracefully(); } } public static void main(String[] args) throws Exception { EchoClient client = new EchoClient("127.0.0.1", 9876); client.start(); } }
package com.geekymv.netty.echo.client; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.util.CharsetUtil; public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> { /** * Called after the connection to the server is established * @param ctx * @throws Exception */ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { // 发送数据到服务端 ctx.writeAndFlush(Unpooled.copiedBuffer("Hello, Netty", CharsetUtil.UTF_8)); } /** * Called after you receive data from the server * @param ctx * @param msg * @throws Exception */ @Override public void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { // 接收服务端发送过来的数据 System.out.println("Client received: " + ByteBufUtil.hexDump(msg.readBytes(msg.readableBytes()))); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } }
服务端
package com.geekymv.netty.echo.server; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; public class EchoServer { private final int port; public EchoServer(int port) { this.port = port; } public void serv() { EventLoopGroup bossGroup = new NioEventLoopGroup(); try { ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup); serverBootstrap.channel(NioServerSocketChannel.class); serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast(new EchoServerHandler()); } }); ChannelFuture channelFuture = serverBootstrap.bind(this.port).sync(); /* the application will wait until the server's channel closes (because we call sync() on the channel's close future). You can now */ channelFuture.channel().closeFuture().sync(); System.out.println("上面一行代码阻塞,输出不会执行"); }catch (Exception e) { e.printStackTrace(); }finally { bossGroup.shutdownGracefully(); } } public static void main(String[] args) { EchoServer server = new EchoServer(9876); server.serv(); } }
package com.geekymv.netty.echo.server; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; /** * Implementing the server/business logic */ public class EchoServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf buf = null; if(msg instanceof ByteBuf) { ByteBuf msgContent = (ByteBuf)msg; buf = msgContent.readBytes(msgContent.readableBytes()); System.out.println("Server received: " + ByteBufUtil.hexDump(buf)); } // System.out.println(buf); // Write the received messages back. // Be aware that this will not flush the messages to the remote peer yet ctx.write(buf); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { // Flush all previous written messages(that are pending) to the remote server peer // and close the channel after the operation is complete. ctx.writeAndFlush(Unpooled.EMPTY_BUFFER) .addListener(ChannelFutureListener.CLOSE); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } }