服务端:
//服务端 public class Server { public static void main(String[] args) { //创建两个线程组 EventLoopGroup connectGroup = new NioEventLoopGroup();//接受客户端连接 EventLoopGroup workGroup = new NioEventLoopGroup();//处理实际业务操作 try {//创建server配置类 ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(connectGroup,workGroup)//支持链式编程,进行配置 //指定使用NioServerSocketChannel这种类型(服务端)的通道 .channel(NioServerSocketChannel.class) //ChannelInitializer:服务器Channel通道初始化设置的抽象类 .childHandler(new ChannelInitializer<SocketChannel>() { @Override //初始化操作:编解码,绑定处理逻辑等 protected void initChannel(SocketChannel channel) throws Exception { //使用 childHandler 去绑定具体的 事件处理器 ChannelPipeline pipeline = channel.pipeline(); pipeline.addLast(new ServerHandler());//绑定服务端数据处理 } }); //绑定端口,调用sync()方法来执行同步阻塞,直到绑定完成 ChannelFuture sync = bootstrap.bind(9527).sync(); //获取该Channel的CloseFuture,并且阻塞当前线程直到绑定的端口关闭才会执行关闭通道 sync.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace(); } finally { //关闭线程组 connectGroup.shutdownGracefully(); workGroup.shutdownGracefully(); } } }
服务端业务处理
/* * 服务端处理数据类 * */ // SimpleChannelInboundHandler: 只处理入站消息(接受到的) public class ServerHandler extends SimpleChannelInboundHandler<ByteBuf> { //CTRL+O: 重写父类方法 //对数据进行处理 @Override protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception { byte[] data=new byte[byteBuf.readableBytes()];//创建byte数组 byteBuf.readBytes(data);//将数据读取到数组中 //转String String str=new String(data,"utf-8"); System.out.println("服务端收到数据:"+str); //返回数据给客户端 Ctrl+Alt+V :自动补全返回值 ByteBuf byteBuf1 = Unpooled.copiedBuffer("我已经接受到数据".getBytes());//转byteBuf channelHandlerContext.writeAndFlush(byteBuf1);//发送给客户端 } //捕获异常 @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace();//打印信息 ctx.close();//关闭通道 } }
客户端
//客户端 public class Client { public static void main(String[] args) throws Exception { //实际业务处理线程组 EventLoopGroup workGroup = new NioEventLoopGroup(); //创建客户端配置类 Bootstrap bootstrap=new Bootstrap(); //链式配置 bootstrap.group(workGroup) .channel(NioSocketChannel.class) //指定客户端类型通道 .handler(new ChannelInitializer<SocketChannel>() { //配置初始化 @Override protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(new ClientHandler());//绑定客户端数据处理对象 } }); //与服务端连接,调用sync()方法来执行同步阻塞,直到连接完成 ChannelFuture sync =bootstrap.connect("127.0.0.1",9527).sync(); //向服务端发送数据 Unpooled: netty提供的工具类,可以将其他类型转为buf类型 sync.channel().writeAndFlush(Unpooled.copiedBuffer("我是客户端".getBytes())); //开启同步阻塞监听,直到断开连接才关闭通道 sync.channel().closeFuture().sync(); workGroup.shutdownGracefully(); } }
客户端业务处理
//客户端处理数据 public class ClientHandler extends SimpleChannelInboundHandler<ByteBuf> { //处理服务端返回的数据 @Override protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception { byte[] data = new byte[byteBuf.readableBytes()];//byteBuf.readableBytes():获取可用的长度 byteBuf.readBytes(data);//数据读取到数组中 String string = new String(data,"utf-8"); System.out.println("客户端接受到服务端返回的数据:"+string); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace();//打印信息 ctx.close();//关闭通道 } }
到这里一个客户端服务端简单通信就完成了,比nio简单多了,是不是,工具用的idea,先开启服务端,再开启客户端: