zoukankan      html  css  js  c++  java
  • netty初试

    netty官网:点击进入

    学习netty之实现一个丢弃服务器

    环境:

    •     JDK1.8
    •     netty5.0+


    步骤:

    1.  实现一个丢弃服务器
    2.  实现一个客户端发送数据


    丢弃服务器的创建

         

    //用于接受客户端的的连接,将连接注册到worker中
        EventLoopGroup boos = new NioEventLoopGroup();
    
        //处理客户端的连接
        EventLoopGroup worker = new NioEventLoopGroup();
    
        //服务端启动类
        ServerBootstrap serverBootstrap = new ServerBootstrap();
    
        ChannelFuture sync = null;
            try {
                ServerBootstrap boot = serverBootstrap.group(boos, worker)
                        .channel(NioServerSocketChannel.class)
                        .childHandler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            protected void initChannel(SocketChannel ch) throws Exception {
                            //自己继承了ChannelHandlerAdapter
                                ch.pipeline().addLast(new DiscardHandler());
                            }
                        });
                //绑定端口,接受连接
                sync = boot.bind(10980).sync();
                System.out.println("丢弃服务器启动...");
                //等待服务器关闭
                sync.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally{
                if(null != sync){
                    try {
                        //管理连接
                        sync.channel().closeFuture().sync();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //处理完客户端的请求后在优雅的关闭
                boos.shutdownGracefully();
                worker.shutdownGracefully();
            } 

    DiscardHandler实现:

        public class DiscardHandler extends ChannelHandlerAdapter {
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            System.out.println("客户端断开连接");
            ctx.writeAndFlush(Unpooled.copiedBuffer("有一个客户端断开连接".getBytes("UTF-8")));
            cause.printStackTrace();
        }
    
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            服务器端本地查看发送来的信息
            ByteBuf msg1 = (ByteBuf) msg;
            byte[] buf = new byte[msg1.readableBytes()];
            msg1.readBytes(buf);
            String s = new String(buf, "UTF-8");
            System.out.println("客户端发来的信息:"+s);
            //直接丢弃信息
            ReferenceCountUtil.release(msg);
        }
    
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            ctx.writeAndFlush(Unpooled.copiedBuffer("---连接成功:",CharsetUtil.UTF_8));
        }
      }

    客户端发送数据:

               NioEventLoopGroup clientGroup = null;
            try {
                clientGroup = new NioEventLoopGroup();
                Bootstrap bootstrap = new Bootstrap();
                ChannelFuture connect = bootstrap.group(clientGroup)
                        .channel(NioSocketChannel.class)
                        .handler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            protected void initChannel(SocketChannel ch) throws Exception {
                            //自定义客户端的发送逻辑
                                ch.pipeline().addLast(new ClientHandler());
                            }
                        })
                        .connect("localhost", 10980);
                while (true) {
                    Scanner scanner = new Scanner(System.in);
                    System.out.println("输入 exit 结束:");
                    String s = scanner.nextLine();
    
                    if (!Objects.isNull(s) && s.equals("exit")) {
                        connect.channel().writeAndFlush(Unpooled.copiedBuffer(s.getBytes("UTF-8")))
                       //关闭监听器,代表ChannelFuture执行返回后,关闭连接。
                                .addListener(ChannelFutureListener.CLOSE);
                        break;
                    }
                    connect.channel().writeAndFlush(Unpooled
                                            .copiedBuffer(s.getBytes("UTF-8")));
                }
            }catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } finally {
                clientGroup.shutdownGracefully();
            }
        }


    ClientHandler实现:

        public class ClientHandler extends ChannelHandlerAdapter {
    
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            ByteBuf msg1 = (ByteBuf) msg;
            byte[] buf = new byte[msg1.readableBytes()];
            msg1.readBytes(buf);
            System.out.println("服务器返回的信息:"+new String(buf,"UTF-8"));
            //释放内存
            ReferenceCountUtil.release(msg);
    
    
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            ctx.close();
            System.out.println(cause.getMessage());
        }
    
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            ctx.writeAndFlush(Unpooled.copiedBuffer("HI 首次连接".getBytes("UTF-8")));
        }
    
        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
            System.out.println("数据发送成功");
        }
    
        }


    问题:

        开始是继承了SimpleChannleINBoundAdpater<ByteBuf>
        在channelReadComplete中 发送 ctx.writeAndFlush()中发送服务器,会造成死循环,客户端一直发送信息给服务器,造成资源浪费
        其次,在发发送数据的时候直接发送ByteBuf对象,客户端是无法接受到的需要转换成
        Unpooled.copiedBuffer(byte[]);    发送数据

    PS:

        可以实现在线用户数量梳理:    
        在服务端初始化一个AtomicInteger类,每次客户端连接的时候将此数值原子性+1,
        在客户端断开的时候将其-1.每个用户连接后,将其信息发送出去。

    平凡是我的一个标签
  • 相关阅读:
    中国科学技术大学2021年数学分析考研试卷
    中国科学技术大学2021年高等代数考研试卷
    中国海洋大学2021年数学分析考研试卷
    中国海洋大学2021年高等代数考研试卷
    中北大学2021年高等代数考研试卷
    数学分析教程第3版参考解答1.6自然对数的底
    数学分析中的问题与方法参考解答第1章极限论
    郑州大学2021年数学分析考研试卷
    郑州大学2021年高等代数考研试卷
    浙江师范大学2021年高等代数考研试卷
  • 原文地址:https://www.cnblogs.com/guyanzy/p/10777086.html
Copyright © 2011-2022 走看看