当前位置:网站首页>NiO related knowledge points (I)

NiO related knowledge points (I)

2022-07-07 05:00:00 Certainly tomorrow

Catalog

BIO、NIO difference

Conceptually

Specifically reflect

BIO

NIO


BIO、NIO difference

Conceptually

BIO: Blocking IO.

NIO: Non blocking IO.

Specifically reflect

BIO

BIO Server code . The specific blocking place is written in the code comment .

    public static void main(String[] args) {
        try {
            ServerSocket socket = new ServerSocket(9000);
            while (true){
                System.out.println(" Waiting for the connection ");
                Socket accept = socket.accept();// Block if connection is not obtained 
                System.out.println(" There is a client connection ");
                handler(accept);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void handler(Socket accept) throws IOException {
        byte[] bytes = new byte[1024];
        System.out.println(" Ready to read ");
        int read = accept.getInputStream().read(bytes); // Unread data blocks 
        System.out.println(" Finished reading ");
        if (read!=-1){
            System.out.println(" The data is :"+new String(bytes,0,read));
        }
        // The data has not been processed , Then block the next data 
    }

BIO It's too limited , The above code allows only one connection to be processed at a time . Let's make a little transformation , Even if we put handler Methods are placed in multiple threads , Can handle multiple messages . But there are still big problems : If too many requests cause memory overflow , Or there are multiple connections but empty connections that never send messages ( Waste of resources ).

BIO It has long been unable to meet the growing number of users . If your concurrency is small , It can still be used BIO Of .

NIO

NIO Server code . Essence is written in the notes .

    static List<SocketChannel> list = new ArrayList<SocketChannel>();
    public static void main(String[] args) throws IOException {
        // Set port 
        ServerSocketChannel serverSocket = ServerSocketChannel.open();
        serverSocket.socket().bind(new InetSocketAddress(9000));
        // Set the connection to non blocking 
        serverSocket.configureBlocking(false);
        System.out.println(" Service started successfully ");
        // Non blocking loop 
        while (true){
            SocketChannel accept = serverSocket.accept();
            // If there is a connection 
            if(accept!=null){
                System.out.println(" There is a client connection ");
                // Set the pipe to non blocking 
                accept.configureBlocking(false);
                list.add(accept);
            }
            Iterator<SocketChannel> iterator = list.iterator();
            // Traverse the pipeline to get data ,read It's not blocked .
            while (iterator.hasNext()){
                SocketChannel sc = iterator.next();
                ByteBuffer buffer = ByteBuffer.allocate(128);
                int read = sc.read(buffer);
                if(read>0){
                    System.out.println(" Received a message :"+new String(buffer.array()));
                }else if(read==-1){
                    iterator.remove();
                    System.out.println(" Client disconnected ");
                }
            }
        }

    }

Naturally, it can support multiple connections , You can set the connection and read Non blocking . One thread handles multiple clients . Then use traversal connection to receive data .

above NIO Problems with the program :while(iterator.hasNext()) Traversal efficiency is low .

To solve this problem , Introduced selector multiplexer . Separate connection events from read-write events , If there is a write event , Just traverse the written socket. The code is as follows , Explain in notes .

    public static void main(String[] args) throws IOException {
        // Open ports 
        ServerSocketChannel serverSocket = ServerSocketChannel.open();
        serverSocket.socket().bind(new InetSocketAddress(9000));
        serverSocket.configureBlocking(false);
        // open selector Handle channel.linux Helped us create a epoll example (epoll_create)
        Selector selector = Selector.open();
        // hold serverSocket Sign up to selector, And specify the listening connection 
        SelectionKey selectionKey = serverSocket.register(selector, SelectionKey.OP_ACCEPT);
        System.out.println(" Service started successfully ");
        while (true){
            // Blocking waits for events to be processed to occur 
            selector.select(); // Bottom call epoll_ctl function , Enable listening . call epoll_wait Go see another                                                 
                               //  Whether the collection has active events , If not, it will block .
            // To get in selector All the events inside 
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            // Traverse processing 
            while (iterator.hasNext()){
                SelectionKey key = iterator.next();
                // If the event represents a connection 
                if(key.isAcceptable()){
                    ServerSocketChannel server=(ServerSocketChannel)key.channel();
                    SocketChannel socketChannel = server.accept();
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selector,SelectionKey.OP_READ);
                    System.out.println(" Client connection successful ");
                }else if(key.isReadable()){ // If the event represents readable 
                    SocketChannel socketChannel = (SocketChannel) key.channel();
                    ByteBuffer byteBuffer = ByteBuffer.allocate(128);
                    int len = socketChannel.read(byteBuffer);
                    if (len>0){
                        System.out.println(" receive messages :"+new String(byteBuffer.array()));
                    }else if(len==-1){
                        System.out.println(" disconnect ");
                        socketChannel.close();
                    }
                }
                iterator.remove();
            }
        }
    }

This solves the problem of invalid traversal . to want to Learn more epoll, You can read this article

Java Medium socket (socket) And introduction to relevant concepts _ If you have bad luck, try to make it up -CSDN Blog Getting started with sockets , Those who don't understand can start learning https://blog.csdn.net/wai_58934/article/details/122848372?spm=1001.2014.3001.5501 That's all for today , White whoring live broadcast open class , Continue tomorrow

原网站

版权声明
本文为[Certainly tomorrow]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202130739593172.html