Issue with SelectionKey not getting removed by iterator.remove()
843790Jul 20 2008 — edited Jul 21 2008I have written a piece of code which is supposed to read from a Socket in a single thread. The code works fine until I close the telnet client. Once if I quit the telnet client using ctrl + ]+q the handler will get in to an infinite loop. I have gone through the code and could make out that it.remove() is not removing the event from the selector.
Here is my code and pls help me out with how to remove the SelectionKey from the Selector's Key list.
package myjava.newio;
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.Set;
public class MultiPortEcho
{
static int ct;
Selector selector;
Selector readSelector;
SelectionKey k;
public MultiPortEcho( ) throws IOException {
go();
}
private void go() throws IOException {
// Create a new selector
selector = Selector.open();
readSelector=Selector.open();
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking( false );
ServerSocket ss = ssc.socket();
InetSocketAddress address = new InetSocketAddress(10300);
ss.bind( address );
SelectionKey key = ssc.register( selector, SelectionKey.OP_ACCEPT );
System.out.println( "Going to listen on "+10300 );
while (true)
{
int num = selector.select();
Set <SelectionKey>selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> it = selectedKeys.iterator();
while (it.hasNext())
{
SelectionKey Connectevent = (SelectionKey)it.next();
if ((Connectevent.readyOps() & SelectionKey.OP_ACCEPT)== SelectionKey.OP_ACCEPT) {
ct++;
ServerSocketChannel serverSocketChannel = (ServerSocketChannel)Connectevent.channel();
SocketChannel sc = serverSocketChannel.accept();
sc.configureBlocking( false );
readSelector.wakeup();
k= sc.register( readSelector, SelectionKey.OP_READ );
if(ct<2){
new Thread ( new Runnable(){
public void run() {
try {
handleConnection();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
try{
it.remove();
}catch (ConcurrentModificationException cme){
cme.printStackTrace();
}
System.out.println( "Got connection from "+sc );
}
}
}
}
public void handleConnection() throws IOException{
while (true)
{
ByteBuffer echoBuffer = ByteBuffer.allocate( 1024 );
//readSelector.wakeup();
int num = readSelector.select();
Set <SelectionKey>selectedKeys = readSelector.selectedKeys();
Iterator<SelectionKey> it = selectedKeys.iterator();
while (it.hasNext())
{
SelectionKey readEvent = (SelectionKey)it.next();
if ((readEvent.readyOps() & SelectionKey.OP_READ)== SelectionKey.OP_READ) {
SocketChannel sc = (SocketChannel)readEvent.channel();
int bytesEchoed = 0;
while (true) {
echoBuffer.clear();
int r;
try {
r = sc.read( echoBuffer );
if (r<=0) {
break;
}
echoBuffer.flip();
sc.write( echoBuffer );
bytesEchoed += r;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println( "Echoed "+bytesEchoed+" from "+sc );
try{
it.remove();
}catch (ConcurrentModificationException cme){
cme.printStackTrace();
}
}
}
}
}
static public void main( String args[] ) throws Exception {
new MultiPortEcho( );
}
}
The code works fine until I quit the client session. Once I quit the client session it gets into a infinite loop as the it.remove () of the handleConnection is not removing the readEvent from the selectedKey set!!!!!!!
please help me.