Java NIO 簡單使用
總結了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事件就緒--
++++++++++++++++++++++++++++++++++++++++++
>>>>>等待感興趣事件已經就緒的通道>>>>