效果图
Server端代码
package cn.itcast.netty.basic; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.util.CharsetUtil; //服务器端的业务处理类 public class NettyServerHandler extends ChannelInboundHandlerAdapter { //读取数据事件 public void channelRead(ChannelHandlerContext ctx,Object msg){ System.out.println("Server:"+ctx); ByteBuf buf=(ByteBuf) msg; System.out.println("客户端发来的消息:"+buf.toString(CharsetUtil.UTF_8)); } //数据读取完毕事件 public void channelReadComplete(ChannelHandlerContext ctx){ ctx.writeAndFlush(Unpooled.copiedBuffer("就是没钱",CharsetUtil.UTF_8)); } //异常发生事件 public void exceptionCaught(ChannelHandlerContext ctx,Throwable t){ ctx.close(); } }
package cn.itcast.netty.basic; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; 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 NettyServer { public static void main(String[] args) throws Exception{ //1. 创建一个线程组:接收客户端连接 EventLoopGroup bossGroup =new NioEventLoopGroup(); //2. 创建一个线程组:处理网络操作 EventLoopGroup workerGroup =new NioEventLoopGroup(); //3. 创建服务器端启动助手来配置参数 ServerBootstrap b=new ServerBootstrap(); b.group(bossGroup,workerGroup) //4.设置两个线程组 .channel(NioServerSocketChannel.class) //5.使用NioServerSocketChannel作为服务器端通道的实现 .option(ChannelOption.SO_BACKLOG,128) //6.设置线程队列中等待连接的个数 .childOption(ChannelOption.SO_KEEPALIVE,true) //7.保持活动连接状态 .childHandler(new ChannelInitializer<SocketChannel>() { //8. 创建一个通道初始化对象 public void initChannel(SocketChannel sc){ //9. 往Pipeline链中添加自定义的handler类 sc.pipeline().addLast(new NettyServerHandler()); } }); System.out.println("......Server is ready......"); ChannelFuture cf=b.bind(9999).sync(); //10. 绑定端口 bind方法是异步的 sync方法是同步阻塞的 System.out.println("......Server is starting......"); //11. 关闭通道,关闭线程组 cf.channel().closeFuture().sync(); //异步 bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } }
客户端代码
package cn.itcast.netty.basic; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.util.CharsetUtil; //客户端业务处理类 public class NettyClientHandler extends ChannelInboundHandlerAdapter { //通道就绪事件 public void channelActive(ChannelHandlerContext ctx){ System.out.println("Client:"+ctx); ctx.writeAndFlush(Unpooled.copiedBuffer("老板,还钱吧",CharsetUtil.UTF_8)); } //读取数据事件 public void channelRead(ChannelHandlerContext ctx,Object msg){ ByteBuf buf=(ByteBuf) msg; System.out.println("服务器端发来的消息:"+buf.toString(CharsetUtil.UTF_8)); } }
package cn.itcast.netty.basic; 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; //网络客户端 public class NettyClient { public static void main(String[] args) throws Exception{ //1. 创建一个线程组 EventLoopGroup group=new NioEventLoopGroup(); //2. 创建客户端的启动助手,完成相关配置 Bootstrap b=new Bootstrap(); b.group(group) //3. 设置线程组 .channel(NioSocketChannel.class) //4. 设置客户端通道的实现类 .handler(new ChannelInitializer<SocketChannel>() { //5. 创建一个通道初始化对象 @Override protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(new NettyClientHandler()); //6.往Pipeline链中添加自定义的handler } }); System.out.println("......Client is ready......"); //7.启动客户端去连接服务器端 connect方法是异步的 sync方法是同步阻塞的 ChannelFuture cf=b.connect("127.0.0.1",9999).sync(); //8.关闭连接(异步非阻塞) cf.channel().closeFuture().sync(); } }