Netty Java原生和Netty网络的API比较

摘要:
“.getBytes());对于(;;){try{selector.select();}捕获{例如printStackTrace();//handleeexceptionbreak;}设置readyKeys=选择器。selectedKeys();迭代器<SelectionKey>迭代器=readyKeys。迭代器();而{SelectionKeykey=iterator.next();iterator.remove();尝试{if{ServerSocketChannelserver=key.channel();SocketChannel client=server.accept());client.configureBlocking;client.register;System.out.println;}如果{SocketChannelclient=key.channel();ByteBufferbuffer=key.attachment();而{if{break;}}客户close();}}捕获{key.cancel();尝试{key.channel().close();}Catch{//ignorenclose}只有NIO和Epoll支持零拷贝。对于Linux,自Linux内核版本2.5.44以来,epoll(一种高度可扩展的I/O事件通知功能)提供了比旧的POSIXselect和poll系统调用更好的性能。LinuxJDKNIOAPI使用这些epoll调用,使用起来很简单。它只需要用EpollEventGroup替换NioEventLoopGroup,并替换NioServerSocketChannel。使用EpollServerSocketChannel.class初始化。

 

Java原生阻塞IO

public class PlainOioServer {
    public void serve(int port) throws IOException {
        final ServerSocket socket = new ServerSocket(port);
        try {
            for(;;) {
                final Socket clientSocket = socket.accept();
                System.out.println(
                        "Accepted connection from " + clientSocket);
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        OutputStream out;
                        try {
                            out = clientSocket.getOutputStream();
                            out.write("Hi!
".getBytes(
                                    Charset.forName("UTF-8")));
                            out.flush();
                            clientSocket.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        } finally {
                            try {
                                clientSocket.close();
                            } catch (IOException ex) {
                                // ignore on close
                            }
                        }
                    }
                }).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Java原生NIO

nio:选择并处理状态的变化

Netty Java原生和Netty网络的API比较第1张

public class PlainNioServer {
    public void serve(int port) throws IOException {
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        serverChannel.configureBlocking(false);
        ServerSocket ss = serverChannel.socket();
        InetSocketAddress address = new InetSocketAddress(port);
        ss.bind(address);
        Selector selector = Selector.open();
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        final ByteBuffer msg = ByteBuffer.wrap("Hi!
".getBytes());
        for (;;){
            try {
                selector.select();
            } catch (IOException ex) {
                ex.printStackTrace();
                //handle exception
                break;
            }
            Set<SelectionKey> readyKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = readyKeys.iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                iterator.remove();
                try {
                    if (key.isAcceptable()) {
                        ServerSocketChannel server =
                                (ServerSocketChannel) key.channel();
                        SocketChannel client = server.accept();
                        client.configureBlocking(false);
                        client.register(selector, SelectionKey.OP_WRITE |
                                SelectionKey.OP_READ, msg.duplicate());
                        System.out.println(
                                "Accepted connection from " + client);
                    }
                    if (key.isWritable()) {
                        SocketChannel client =
                                (SocketChannel) key.channel();
                        ByteBuffer buffer =
                                (ByteBuffer) key.attachment();
                        while (buffer.hasRemaining()) {
                            if (client.write(buffer) == 0) {
                                break;
                            }
                        }
                        client.close();
                    }
                } catch (IOException ex) {
                    key.cancel();
                    try {
                        key.channel().close();
                    } catch (IOException cex) {
                        // ignore on close
                    }
                }
            }
        }
    }
}

只有NIO和Epoll支持零拷贝

Netty Java原生和Netty网络的API比较第2张

  • 针对于Linux,自Linux内核版本 2.5.44后,引入epoll——一个高度可扩展的I/O事件通知特性,提供了比旧的POSIX select和poll系统调用更好的性能,Linux JDK NIO API使用了这些epoll调用

用法简单,只需要将NioEventLoopGroup替换为EpollEventGroup,并且把NioServerSocketChannel.class替换为EpollServerSocketChannel.class即可。

String os = System.getProperty("os.name");  
if(os.toLowerCase().startsWith("win")){  
  System.out.println(os + " can't gunzip");  
}

Netty实现阻塞IO

OIO的处理逻辑

Netty Java原生和Netty网络的API比较第3张

public class NettyOioServer {
    public void server(int port)
            throws Exception {
        final ByteBuf buf =
                Unpooled.unreleasableBuffer(Unpooled.copiedBuffer("Hi!
", Charset.forName("UTF-8")));
        EventLoopGroup group = new OioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(group)
                    .channel(OioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(port))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch)
                                throws Exception {
                                ch.pipeline().addLast(
                                    new ChannelInboundHandlerAdapter() {
                                        @Override
                                        public void channelActive(
                                                ChannelHandlerContext ctx)
                                                throws Exception {
                                            ctx.writeAndFlush(buf.duplicate())
                                                    .addListener(
                                                            ChannelFutureListener.CLOSE);
                                        }
                                    });
                        }
                    });
            ChannelFuture f = b.bind().sync();
            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully().sync();
        }
    }
}

Netty实现NIO

public class NettyNioServer {
    public void server(int port) throws Exception {
        final ByteBuf buf =
                Unpooled.unreleasableBuffer(Unpooled.copiedBuffer("Hi!
",
                        Charset.forName("UTF-8")));
        NioEventLoopGroup group = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(group).channel(NioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(port))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                                      @Override
                                      public void initChannel(SocketChannel ch)
                                              throws Exception {
                                              ch.pipeline().addLast(
                                                  new ChannelInboundHandlerAdapter() {
                                                      @Override
                                                      public void channelActive(
                                                              ChannelHandlerContext ctx) throws Exception {
                                                                ctx.writeAndFlush(buf.duplicate())
                                                                  .addListener(
                                                                          ChannelFutureListener.CLOSE);
                                                      }
                                                  });
                                      }
                                  }
                    );
            ChannelFuture f = b.bind().sync();
            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully().sync();
        }
    }
}
 

免责声明:文章转载自《Netty Java原生和Netty网络的API比较》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Ubuntu 系统安装 数据恢复软件 ext4magic 通过RPM方式act_window 属性下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Netty入门1之----认识Netty

Netty 什么是Netty? Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架。 Netty 是一个广泛使用的 Java 网络编程框架(Netty 在 2011 年获得了Duke's Choice Award,见https://www.java.net/dukescho...

Netty源码分析(前言, 概述及目录)

Netty源码分析(完整版) 前言 前段时间公司准备改造redis的客户端, 原生的客户端是阻塞式链接, 并且链接池初始化的链接数并不高, 高并发场景会有获取不到连接的尴尬, 所以考虑了用netty长连接解决连接数和阻塞io问题 为此详细阅读了netty源码, 熟悉了netty的各个主要的特性以及疏通各个组件的关联关系, 所以想把这段时间的学习内容, 学...

Netty源码剖析-关闭服务

参考文献:极客时间傅健老师的《Netty源码剖析与实战》Talk is cheap.show me the code! ----主线:    ----源码:   先在服务端加个断点和修改下代码:如图:  然后启动server和client;然后跳过bossGroup到workerGroup;进入workerGroup的关闭:在此之前呢,先在NioEven...

Netty异步编程模型上的同步调用

看简单的一个小程序,说明什么是同步调用:所谓的同步调用就是调用一个方法,然后返回一个结果。(这个过程一直是阻塞的,直到返回值)。 而netty中异步编程模型中不是同步调用,读写都是在handler中处理。 关于同步调用和异步调用请参考http://blog.csdn.net/dan_blog/article/details/7897852 服务器端程序...

netty之SSL协议-netty学习笔记(8)-20210806

1、SSL/TLS简介 协议是Web浏览器与Web服务器之间安全交换信息的协议,提供两个基本的安全服务:鉴别与保密。 1.1、作用 不使用SSL/TLS的HTTP通信,就是不加密的通信。所有信息明文传播,带来了三大风险。 窃听风险(eavesdropping):第三方可以获知通信内容。 篡改风险(tampering):第三方可以修改通信内容。 冒...

简单谈谈Netty的高性能之道

传统RPC 调用性能差的三宗罪 网络传输方式问题:传统的RPC 框架或者基于RMI 等方式的远程服务(过程)调用采用了同步阻塞IO,当客户端的并发压力或者网络时延增大之后,同步阻塞IO 会由于频繁的wait 导致IO 线程经常性的阻塞,由于线程无法高效的工作,IO 处理能力自然下降。下面,我们通过BIO 通信模型图看下BIO 通信的弊端:   采用BIO...