com.nio.Server
package com.nio;
import java.io.IOException;
import java.net.InetSocketAddress;
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 Server {
private Selector selector = null;
public Server() throws IOException{
// register the server
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
int port = 8080;
InetSocketAddress endpoint = new InetSocketAddress(port );
ssc.socket().bind(endpoint);
selector = Selector.open();
ssc.register(selector, SelectionKey.OP_ACCEPT);
}
public void start() throws IOException{
while(true){
int num = selector.select();
if(num>0){
Set<SelectionKey> selectionKeySet = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeySet.iterator();
while(iterator.hasNext()){
SelectionKey key = iterator.next();
iterator.remove();// must remove it
if (key.isAcceptable()) {
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
SocketChannel sc = serverSocketChannel.accept();
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ);
}else if (key.isReadable()) {
System.out.println("do read ...");
SocketChannel sc = (SocketChannel) key.channel();
sc.register(selector, SelectionKey.OP_WRITE);
}else if (key.isWritable()) {
System.out.println("do write ...");
SocketChannel sc = (SocketChannel) key.channel();
sc.close();
key.cancel();
}
}
}
}
}
public static void main(String[] args) throws Exception {
new Server().start();
}
}
com.nio.Client
package com.nio;
import java.io.IOException;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws IOException{
System.out.println("client start ... ");
Socket socket = new Socket("localhost",8080);
socket.close();
System.out.println("client end ... ");
}
}
Note:
1. 在使用Iterator迭代SelectionKey的后,必须调用Iterator.remove(). 因为select()只会向selector所关联的键集合中添加元素,如果不移除每个处理过的键,它就会在下次select()方法时仍然保留在集合中。
2. 不要轻易使用SelectionKey.cancel(). cancel 会终止selector 和 key关联的Channel的联系。