Java NIO 簡單使用

jopen 10年前發布 | 19K 次閱讀 Java NIO Java開發

總結了Java NIO的基本使用方法

 

看代碼

package nio2;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class PlainNioServer {

    public void serve(int port) throws IOException {
        System.out.println("Listening for connections on port " + port);

        //聲明服務器端ServerSocketChannel通道
        ServerSocketChannel serverChannel;
        //聲明一個多路復用器Selector
        Selector selector;

        serverChannel = ServerSocketChannel.open();
        ServerSocket ss = serverChannel.socket();
        InetSocketAddress address = new InetSocketAddress(port);
        ss.bind(address);

        serverChannel.configureBlocking(false);
        selector = Selector.open();

        /**
         * Registers this channel with the given selector, returning a selection
         * key.
         * The interest set for the resulting key
         */
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        final ByteBuffer msg = ByteBuffer.wrap("Hi!\r\n".getBytes());

        while (true) {
            try {
                System.out.println(">>>>>等待感興趣事件已經就緒的通道>>>>");
                selector.select();
            } catch (IOException ex) {
                ex.printStackTrace();
                break;
            }

            System.out.println(">>>>>返回就緒通道的鍵值>>>>>");
            Set readyKeys = selector.selectedKeys();
            Iterator iterator = readyKeys.iterator();

            while (iterator.hasNext()) {
                SelectionKey key = (SelectionKey) iterator.next();
                iterator.remove();
                try {
                    if (key.isAcceptable()) {
                        System.out.println("--該鍵表示的通道的Accept事件就緒--");
                        ServerSocketChannel server = (ServerSocketChannel) key.channel();
                        SocketChannel client = server.accept();
                        System.out.println("Accepted connection from " + client);
                        client.configureBlocking(false);
                        client.register(selector, SelectionKey.OP_WRITE | SelectionKey.OP_READ, msg.duplicate());
                    }
                    if (key.isWritable()) {
                        System.out.println("--該鍵表示的通道的Writable事件就緒--");
                        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) {
                    }
                }

                System.out.println("++++++++++++++++++++++++++++++++++++++++++\r\n");
            }
        }
    }

    public static void main(String args[]) throws IOException {
        int port = 8080;
        PlainNioServer plainNioServer = new PlainNioServer();
        plainNioServer.serve(port);
    }
}

看結果分析Java NIO的處理過程

Listening for connections on port 8080

>>>>>等待感興趣事件已經就緒的通道>>>>

>>>>>返回就緒通道的鍵值>>>>>

--該鍵表示的通道的Accept事件就緒--

Accepted connection from java.nio.channels.SocketChannel[connected local=/127.0.0.1:8080 remote=/127.0.0.1:63535]

++++++++++++++++++++++++++++++++++++++++++

 

>>>>>等待感興趣事件已經就緒的通道>>>>

>>>>>返回就緒通道的鍵值>>>>>

--該鍵表示的通道的Writable事件就緒--

++++++++++++++++++++++++++++++++++++++++++

 

>>>>>等待感興趣事件已經就緒的通道>>>>

>>>>>返回就緒通道的鍵值>>>>>

--該鍵表示的通道的Accept事件就緒--

Accepted connection from java.nio.channels.SocketChannel[connected local=/127.0.0.1:8080 remote=/127.0.0.1:63536]

++++++++++++++++++++++++++++++++++++++++++

 

>>>>>等待感興趣事件已經就緒的通道>>>>

>>>>>返回就緒通道的鍵值>>>>>

--該鍵表示的通道的Writable事件就緒--

++++++++++++++++++++++++++++++++++++++++++

 

>>>>>等待感興趣事件已經就緒的通道>>>>

>>>>>返回就緒通道的鍵值>>>>>

--該鍵表示的通道的Accept事件就緒--

Accepted connection from java.nio.channels.SocketChannel[connected local=/127.0.0.1:8080 remote=/127.0.0.1:63538]

++++++++++++++++++++++++++++++++++++++++++

 

>>>>>等待感興趣事件已經就緒的通道>>>>

>>>>>返回就緒通道的鍵值>>>>>

--該鍵表示的通道的Writable事件就緒--

++++++++++++++++++++++++++++++++++++++++++

 

>>>>>等待感興趣事件已經就緒的通道>>>>

>>>>>返回就緒通道的鍵值>>>>>

--該鍵表示的通道的Accept事件就緒--

Accepted connection from java.nio.channels.SocketChannel[connected local=/127.0.0.1:8080 remote=/127.0.0.1:63539]

++++++++++++++++++++++++++++++++++++++++++

 

>>>>>等待感興趣事件已經就緒的通道>>>>

>>>>>返回就緒通道的鍵值>>>>>

--該鍵表示的通道的Writable事件就緒--

++++++++++++++++++++++++++++++++++++++++++

 

>>>>>等待感興趣事件已經就緒的通道>>>>

>>>>>返回就緒通道的鍵值>>>>>

--該鍵表示的通道的Accept事件就緒--

Accepted connection from java.nio.channels.SocketChannel[connected local=/127.0.0.1:8080 remote=/127.0.0.1:63540]

++++++++++++++++++++++++++++++++++++++++++

 

>>>>>等待感興趣事件已經就緒的通道>>>>

>>>>>返回就緒通道的鍵值>>>>>

--該鍵表示的通道的Writable事件就緒--

++++++++++++++++++++++++++++++++++++++++++

 

>>>>>等待感興趣事件已經就緒的通道>>>>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!