<JDK 1.4>
(Selectable)Channel
has
Selector
has
SelectionKey 인데 Selector를 서버채널과 클라이언트 채널에 동시에 등록해 accept와 read동시 수행 가능.
<JDK1.6 >의
java.nio.channels.SelectorProvider 는 linux시스템의 epoll을 구현. select=O(n), epoll=O(1)
nio = non-blocking io 임.
=========Selector 예제===== 서버 thread=====
//nio version
public void run(){
ServerSocketChannel ssc=null;
try{
//for SSC
InetSocketAddress addr = new InetSocketAddress(1990);
ssc = ServerSocketChannel.open();
ssc.socket().bind(addr);
//for Selector
Selector selector=Selector.open();
ssc.configureBlocking(false); //make nonBlocking accept()
ssc.register(selector, SelectionKey.OP_ACCEPT);
while (true){ //select for accept While
int numKeys = selector.select(); //select is non Blocking.
if (numKeys > 0){
//System.out.print(" numKeys:" + numKeys); //too much call
Set<SelectionKey> keySet = selector.selectedKeys(); /// Must be selectedKeys.
Iterator<SelectionKey> it = keySet.iterator();
while( it.hasNext()) {
SelectionKey key = it.next();
if( (key.readyOps() & SelectionKey.OP_ACCEPT)==SelectionKey.OP_ACCEPT){
SocketChannel csc = ((ServerSocketChannel) key.channel()).accept();
csc.configureBlocking(false);
System.out.println(" [Server] Client Connected ------"+csc);
//read Key register
csc.register(selector, SelectionKey.OP_READ);
it.remove();//delete key
}else if( (key.readyOps() & SelectionKey.OP_READ)==SelectionKey.OP_READ){
SocketChannel csc = (SocketChannel) key.channel();
//System.out.println(" [Server] Client READ Event ------"+csc);
readFromClient(csc);
it.remove();//delete key
}
}
}
Thread.sleep(10);
} //while
}catch (Exception e){
e.printStackTrace();
}finally{
try{
if(ssc!=null) ssc.close();
}catch (IOException e){}
}
}//run