服务端启动流程
1package com.example.netty; 2 3import com.example.netty.handler.HelloServerHandler; 4import io.netty.bootstrap.ServerBootstrap; 5import io.netty.channel.ChannelInitializer; 6import io.netty.channel.nio.NioEventLoopGroup; 7import io.netty.channel.socket.SocketChannel; 8import io.netty.channel.socket.nio.NioServerSocketChannel; 9 10public class HelloServer { 11 12 public static void main(String[] args) { 13 NioEventLoopGroup bossGroup = new NioEventLoopGroup(); 14 NioEventLoopGroup workerGroup = new NioEventLoopGroup(); 15 16 ServerBootstrap serverBootstrap = new ServerBootstrap(); 17 //1. 指定线程组 18 serverBootstrap.group(bossGroup, workerGroup) 19 .localAddress(8000)//2. 指定端口 20 .channel(NioServerSocketChannel.class)//3. 指定IO模型 21 .childHandler(new ChannelInitializer<SocketChannel>() { 22 @Override 23 protected void initChannel(SocketChannel socketChannel) throws Exception { 24 socketChannel.pipeline().addLast(new HelloServerHandler()); 25 } 26 });//4. 配置业务处理逻辑类 27 //5. 绑定端口 28 serverBootstrap.bind().addListener((future)->{ 29 if(future.isSuccess()){ 30 System.out.println("端口绑定成功"); 31 }else{ 32 System.out.println("端口绑定失败:"+future.cause()); 33 } 34 }); 35 } 36 37}
bossGroup和workerGroup可以看作是传统IO网络编程的两个线程组,bossGroup负责 accept 新的socket连接,workerGroup负责socket连接的读写。ServerBootstrap是服务端引导类,负责.group(bossGroup, workerGroup)配置线程模型;.channel指定IO模型,NioServerSocketChannel.class是NIO模型,OioServerSocketChannel.class是传统IO模型;.childHandler配置业务逻辑处理。.bind()绑定端口,该方法是异步执行,所以需要配置监听器。
服务端业务处理类
1package com.example.netty.handler; 2 3import io.netty.buffer.ByteBuf; 4import io.netty.buffer.Unpooled; 5import io.netty.channel.ChannelHandlerContext; 6import io.netty.channel.ChannelInboundHandlerAdapter; 7import io.netty.util.CharsetUtil; 8 9public class HelloServerHandler extends ChannelInboundHandlerAdapter { 10 11 @Override 12 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 13 ByteBuf byteBuf = (ByteBuf) msg; 14 System.out.println(byteBuf.toString(CharsetUtil.UTF_8)); 15 ctx.writeAndFlush(Unpooled.copiedBuffer("hello client".getBytes())); 16 } 17}
主要打印客户端发送的消息并返回Hello Client。
客户端启动流程
1package com.example.netty; 2 3import com.example.netty.handler.HelloClientHandler; 4import io.netty.bootstrap.Bootstrap; 5import io.netty.channel.ChannelInitializer; 6import io.netty.channel.nio.NioEventLoopGroup; 7import io.netty.channel.socket.SocketChannel; 8import io.netty.channel.socket.nio.NioSocketChannel; 9 10public class HelloClient { 11 12 public static void main(String[] args) { 13 NioEventLoopGroup workerGroup = new NioEventLoopGroup(); 14 15 Bootstrap bootstrap = new Bootstrap(); 16 //1. 配置线程组 17 bootstrap.group(workerGroup) 18 .channel(NioSocketChannel.class)//2. 指定IO模型 19 .remoteAddress("127.0.0.1", 8000)//3. 指定连接ip和端口 20 .handler(new ChannelInitializer<SocketChannel>() { 21 @Override 22 protected void initChannel(SocketChannel socketChannel) throws Exception { 23 socketChannel.pipeline().addLast(new HelloClientHandler()); 24 } 25 });//4. 配置业务处理逻辑 26 //5. 连接 27 bootstrap.connect().addListener(future -> { 28 if(future.isSuccess()){ 29 System.out.println("连接成功"); 30 }else{ 31 System.out.println("连接失败:" + future.cause()); 32 } 33 }); 34 } 35 36}
客户端引导类为Bootstrap,而服务端为ServerBootstrap
业务处理逻辑类
1package com.example.netty.handler; 2 3import io.netty.buffer.ByteBuf; 4import io.netty.buffer.Unpooled; 5import io.netty.channel.ChannelHandlerContext; 6import io.netty.channel.ChannelInboundHandlerAdapter; 7import io.netty.util.CharsetUtil; 8 9public class HelloClientHandler extends ChannelInboundHandlerAdapter { 10 11 @Override 12 public void channelActive(ChannelHandlerContext ctx) throws Exception { 13 ctx.writeAndFlush(Unpooled.copiedBuffer("hello server".getBytes())); 14 } 15 16 @Override 17 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 18 ByteBuf byteBuf = (ByteBuf) msg; 19 System.out.println("recieve from server:" + byteBuf.toString(CharsetUtil.UTF_8)); 20 } 21}
主要在连接后向服务端发送Hello Server,并接受打印服务端返回消息。