netty知识集锦

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

Netty原理浅析
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
分散读,集中写
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
阻塞模式
在这里插入图片描述
非阻塞模式
在这里插入图片描述
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<SelectionKey> 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();
                    }
                }
            }
        }
    }

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

 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<SelectionKey> 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); //无需关注可写事件
                    }
                }
            }
        }
    }

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
每个线程分配一个选择器Worker
在这里插入图片描述

在这里插入图片描述

 class Worker implements Runnable {
        private Thread thread;
        private Selector worker;
        private String name;
        private volatile Boolean isStart = false;
        private ConcurrentLinkedQueue<Runnable> 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<SelectionKey> 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

服务器

public static void main(String[] args) {
    new ServerBootstrap()
            .group(new NioEventLoopGroup())
            .channel(NioServerSocketChannel.class)
            .childHandler(new ChannelInitializer<NioServerSocketChannel>() {
                @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);
}

在这里插入图片描述
客户端

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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
JDK中的Future
在这里插入图片描述
Netty中Future

在这里插入图片描述
netty promise
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
零拷贝,,组合两个ByteBuf
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值