zoukankan      html  css  js  c++  java
  • Java NIO工作原理

    数据通信流程:
    通过selector.select()阻塞方法获取到感兴趣事件的key,根据key定位到channel,通过channel的读写操作进行数据通信。channel的read或者write操作都是通过buffer进行的。

    代码示例

    Server:

    public class Server {
        public static void main(String[] args) throws InterruptedException {
            final int port = 9999;
            try {
                // 初始化server
                ServerSocketChannel server = ServerSocketChannel.open();
                server.socket().bind(new InetSocketAddress(port));
                Selector selector = Selector.open();
    
                // 这一步的设置在register中需要用到,所以要在register之前设置,否则会发生异常
                server.configureBlocking(false);
                SelectionKey serverKey = server.register(selector, SelectionKey.OP_ACCEPT);
    
    
                ByteBuffer buffer = ByteBuffer.allocate(50);
                // 事件循环
                while(true) {
                    Thread.sleep(500);
                    selector.select();
                    Set<SelectionKey> keys = selector.selectedKeys();
                    Iterator<SelectionKey> iterator = keys.iterator();
                    while (iterator.hasNext()) {
                        SelectionKey key = iterator.next();
                        iterator.remove();
                        if (!key.isValid()) {
                            continue;
                        }
                        if (key.isAcceptable()) {
                            ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
                            SocketChannel sc = ssc.accept();
                            sc.configureBlocking(false);
                            sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
    //                        System.out.println(serverKey == key);
                            continue;
                        }
                        if (key.isReadable()) {
                            SocketChannel sc = (SocketChannel) key.channel();
                            sc.read(buffer);
                            buffer.flip();
                            System.out.println(new String(buffer.array(), 0, buffer.limit()));
                        }
                        if (key.isWritable()) {
                            SocketChannel sc = (SocketChannel) key.channel();
                            sc.write(ByteBuffer.wrap("I am server!".getBytes()));
                        }
                    }
                }
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    

    Client:

    public class Client {
        public static void main(String[] args) throws IOException, InterruptedException {
            SocketChannel client = SocketChannel.open();
            client.connect(new InetSocketAddress("localhost", 9999));
            client.configureBlocking(false);
    
            ByteBuffer buffer = ByteBuffer.allocate(50);
            while (true) {
                buffer.clear();
                int i = client.read(buffer);
                if (i > 0) {
                    buffer.flip();
                    System.out.println(new String(buffer.array(), 0, buffer.limit()));
                }
    
                client.write(ByteBuffer.wrap("I am a client!".getBytes()));
                Thread.sleep(500);
            }
        }
    }
    

    其他

    运行在Linux kernel 2.6以后的OS中的Java应用,NIO的底层实现是根据OS提供的io多路复用接口epoll实现。

    参考资料

  • 相关阅读:
    tcp/ip_properties_file
    tcp_ip/udp
    笔记1
    css样式使用_css
    常用的html标签总结_html
    利用sqlalchemy(ORM框架)连接操作mysql_mysql
    mysql基础命令_mysql
    redis使用_python
    RabitMQ使用_python
    后台管理页面2种常用模板_html
  • 原文地址:https://www.cnblogs.com/liushijie/p/5429046.html
Copyright © 2011-2022 走看看