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事件就緒--
++++++++++++++++++++++++++++++++++++++++++
>>>>>等待感興趣事件已經就緒的通道>>>>