netty知识集锦

Netty原理架构解析
【硬核】肝了一月的Netty知识点
简单深入理解高性能网络编程(Netty)中的Reactor模型(图文+代码)

Netty原理浅析
netty知识集锦_第1张图片
netty知识集锦_第2张图片
netty知识集锦_第3张图片
netty知识集锦_第4张图片
netty知识集锦_第5张图片
netty知识集锦_第6张图片
netty知识集锦_第7张图片
netty知识集锦_第8张图片
netty知识集锦_第9张图片
netty知识集锦_第10张图片
分散读,集中写
netty知识集锦_第11张图片
netty知识集锦_第12张图片
netty知识集锦_第13张图片

netty知识集锦_第14张图片
netty知识集锦_第15张图片
netty知识集锦_第16张图片
netty知识集锦_第17张图片

netty知识集锦_第18张图片
netty知识集锦_第19张图片
netty知识集锦_第20张图片
netty知识集锦_第21张图片
阻塞模式
netty知识集锦_第22张图片
非阻塞模式
netty知识集锦_第23张图片
selector模式

      public static void main(String[] args) throws IOException {
        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.configureBlocking(false);
        ssc.bind(new InetSocketAddress(8080));

        Selector selector = Selector.open();
        SelectionKey sscKey  = ssc.register(selector,0,null);
        sscKey.interestOps(SelectionKey.OP_ACCEPT);

        while (true){
            selector.select();
            Iterator iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()){
                SelectionKey key = iterator.next();
                iterator.remove();
                if(key.isAcceptable()){
                    ServerSocketChannel channel =  (ServerSocketChannel)key.channel();
                    SocketChannel sc = channel.accept();
                    sc.configureBlocking(false);
                    SelectionKey scKey = sc.register(selector,0,null);
                    scKey.interestOps(SelectionKey.OP_READ);
                } else if (key.isReadable()){
                    try {
                        SocketChannel channel =  (SocketChannel)key.channel();
                        ByteBuffer buffer = ByteBuffer.allocate(16);
                       int read = channel.read(buffer);
                       if(read==-1){
                           key.cancel(); 
                       } else {
                           buffer.flip();
                       }
                    } catch (IOException e){
                        key.cancel();
                    }
                }
            }
        }
    }

netty知识集锦_第24张图片
netty知识集锦_第25张图片
netty知识集锦_第26张图片

netty知识集锦_第27张图片
netty知识集锦_第28张图片

netty知识集锦_第29张图片

 public static void main(String[] args) throws IOException {
        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.configureBlocking(false);
        ssc.bind(new InetSocketAddress(8080));

        Selector selector = Selector.open();
        SelectionKey sscKey  = ssc.register(selector,0,null);
        sscKey.interestOps(SelectionKey.OP_ACCEPT);

        while (true){
            selector.select();
            Iterator iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()){
                SelectionKey key = iterator.next();
                iterator.remove();
                if(key.isAcceptable()){
                    SocketChannel sc = ssc.accept();
                    sc.configureBlocking(false);
                    SelectionKey scKey = sc.register(selector,SelectionKey.OP_READ,null);
                    //1.向客户端发送大量的数据
                    StringBuffer sb = new StringBuffer();
                    for(int i=0;i<30000;i++){
                        sb.append("a");
                    }
;                  ByteBuffer buffer = Charset.defaultCharset().encode(sb.toString());
                  int write = sc.write(buffer); //2.返回值代表实际写入字节数
                  if(buffer.hasRemaining()){ //3。是否有剩余
                      sscKey.interestOps(scKey.interestOps()|SelectionKey.OP_WRITE); //关注可写事件
                      sscKey.attach(buffer);//把未写完的数据挂到sscKey上
                  }
                } else if(key.isWritable()){
                    ByteBuffer buffer = (ByteBuffer)key.attachment();
                    SocketChannel sc = (SocketChannel)key.channel();
                    sc.write(buffer);
                    if(!buffer.hasRemaining()){
                        key.attach(null); //清除buff
                        key.interestOps(key.interestOps()-SelectionKey.OP_WRITE); //无需关注可写事件
                    }
                }
            }
        }
    }

netty知识集锦_第30张图片
netty知识集锦_第31张图片
netty知识集锦_第32张图片
netty知识集锦_第33张图片
netty知识集锦_第34张图片
netty知识集锦_第35张图片
每个线程分配一个选择器Worker
netty知识集锦_第36张图片

netty知识集锦_第37张图片

 class Worker implements Runnable {
        private Thread thread;
        private Selector worker;
        private String name;
        private volatile Boolean isStart = false;
        private ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue<>();
        public Worker(String name){
            this.name = name;
        }

        public void register(SocketChannel sc){
            if(!isStart){
                this.thread = new Thread(this,name);
                thread.start();
                isStart = true;
            }
            queue.add(()->{
                try {
                    sc.register(worker,SelectionKey.OP_READ,null);
                } catch (ClosedChannelException e){

                }
            });
            worker.wakeup(); //唤醒select方法
        }

        @Override
        public void run() {
            try {
                worker.select();
                Runnable task = queue.poll();
                if (task != null){
                    task.run();
                }
              Iterator iterator =  worker.selectedKeys().iterator();
              while (iterator.hasNext()){
                  SelectionKey key = iterator.next();
                  iterator.remove();;
                  if(key.isReadable()){
                      ByteBuffer buffer = ByteBuffer.allocate(16);
                      SocketChannel channel = (SocketChannel)key.channel();
                      channel.read(buffer);
                      buffer.flip();

                  }
              }
            } catch (IOException e){
            }
        }
    }

也可以如下这种方式:
如果主线程运行的快,也就是selector.select()先执行,阻塞,然后执行selector.wakeUp()被唤醒,然后sc.register…
同理可知其他顺序亦可
netty知识集锦_第38张图片
netty知识集锦_第39张图片
在这里插入图片描述
netty知识集锦_第40张图片
netty知识集锦_第41张图片

netty知识集锦_第42张图片
netty知识集锦_第43张图片

Netty

服务器

public static void main(String[] args) {
    new ServerBootstrap()
            .group(new NioEventLoopGroup())
            .channel(NioServerSocketChannel.class)
            .childHandler(new ChannelInitializer() {
                @Override
                protected void initChannel(NioServerSocketChannel ch) throws Exception {
                    ch.pipeline().addLast(new StringDecoder());
                    ch.pipeline().addLast(new ChannelInboundHandlerAdapter(){
                        @Override
                        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                            super.channelRead(ctx, msg);
                        }
                    });
                }
            })
            .bind(8080);
}

netty知识集锦_第44张图片
客户端

  public static void main(String[] args) throws InterruptedException {
        new Bootstrap()
                .group(new NioEventLoopGroup())
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new StringEncoder());
                    }
                })
                .connect(new InetSocketAddress("localhost",8080))
                .sync()
                .channel()
                .writeAndFlush("hello,world");
    }


netty知识集锦_第45张图片
netty知识集锦_第46张图片


netty知识集锦_第47张图片

netty知识集锦_第48张图片
JDK中的Future
netty知识集锦_第49张图片
Netty中Future

netty知识集锦_第50张图片
netty promise
netty知识集锦_第51张图片
netty知识集锦_第52张图片
netty知识集锦_第53张图片
netty知识集锦_第54张图片
netty知识集锦_第55张图片
netty知识集锦_第56张图片
netty知识集锦_第57张图片
零拷贝,,组合两个ByteBuf
netty知识集锦_第58张图片

你可能感兴趣的:(信息与通信)