ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

NETTY基础知识

2022-02-22 19:02:54  阅读:181  来源: 互联网

标签:NETTY iterator 基础知识 new selectionKey socketChannel channel size


网络IO总体上分为( 这里 的比喻不错):

  1. 阻塞
  2. 非阻塞

阻塞的方式写起来很简单:当链接可读的时候就读一些,不可读的时候就等待:

ServerSocket serverSocket = new ServerSocket(8787);
while (true) {
    Socket socket = serverSocket.accept();
    // TODO 交给线程池进行处理。
}

网络情况不好时阻塞的方式用起来有点蠢,用NIO(有点像SELECT/EPOLL)会靠谱些,当有链接可读时让工作线程来拿数据:

Selector selector = Selector.open();

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress("127.0.0.1", 8787));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

while (true) {
    selector.select();
    Set<SelectionKey> selectionKeySet = selector.selectedKeys();
    Iterator<SelectionKey> iterator = selectionKeySet.iterator();
    while (iterator.hasNext()) {
        SelectionKey selectionKey = iterator.next();
        if (selectionKey.isAcceptable()) {
            ServerSocketChannel channel = (ServerSocketChannel) selectionKey.channel();
            SocketChannel socketChannel = channel.accept();
            socketChannel.configureBlocking(false);
            socketChannel.register(selector, SelectionKey.OP_READ);
        }
        if (selectionKey.isReadable()) {
            SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            int size = socketChannel.read(byteBuffer);
            if (size < 0) {
                selectionKey.cancel();
                socketChannel.close();
            }
            for (int i = 0; i < size; i++) {
                System.out.print((char) byteBuffer.get(i));
            }
        }
        iterator.remove();
    }
}

写最简单的功能都要这么多代码,维护起来也比较痛苦,下面来看如何用NETTY简化开发!

用法

下面的代码用来实现上面的功能:

EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
        .channel(NioServerSocketChannel.class)
        .option(ChannelOption.SO_BACKLOG, 1024)
        .childHandler(new ChannelInitializer<SocketChannel>() {
            protected void initChannel(SocketChannel ch) throws Exception {
                ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
                    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                        ByteBuf buffer = (ByteBuf) msg;
                        int size = buffer.readableBytes();
                        for (int i = 0; i < size; i++) {
                            System.out.print((char) buffer.getByte(i));
                        }
                    }
                });
            }
        });
ChannelFuture future = bootstrap.bind(8787).sync();
future.channel().closeFuture().sync();

看起来也不怎么直观,不要急,先来了解一些NETTY中的概念:

概念含义
Bootstrap/ServerBootstrap配置netty(添加组件、设置参数)
Channel定义I/O操作
ChannelHandlerContext
ChannelHandler处理感兴趣的事件(read、readomplete、bind、flush等)
ChannelPipelineChannelHandler的容器
EventLoop/EventLoopGroup
Future/Promise
Unsafe
ByteBuf处理缓存的工具,比byte[]或者java.nio.ByteBuffer好用一些

标签:NETTY,iterator,基础知识,new,selectionKey,socketChannel,channel,size
来源: https://blog.csdn.net/m0_67109686/article/details/123074953

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有