SocketChannel blocking read() on broken connection
843790Nov 13 2009 — edited Nov 20 2009Hi,
I desperately need help with my socket server. The situation is as follows:
I have got one thread socketchannel server that checks for SelectionKey.OP_READ , then gets some data from client and sends some back. This is game server so it must be fast. So far so good . In general code look like this
if (selKey.isReadable() && selKey.isValid()) {
SocketChannel client = (SocketChannel) selKey.channel( );
//
client.configureBlocking(false);
//READ
ByteBuffer buffer =ByteBuffer.allocate(30);
System.out.println("Waiting"+client.isBlocking());
//
int res= client.read(buffer);
if(res==-1)
{
//handle it
}
Everything is OK untill client breaks connection (for example by closing browser and applet in it). In such situation int res= client.read(buffer) does not return -1 nor 0, instead it blocks whole loop. Javadoc says that it should return -1 or 0 but client.read blocks despite client.configureBlocking(false). Mainly it is problem of detecting broken connection but I know there is no reasonable way to do that. At http://forums.sun.com/thread.jspa?forumID=4&threadID=435661 I have found some ugly solution:
1) implement some kind of keep alive or no-op message in your protocol and send it on a regular basis.
2) implement an idle timer that closes sockets that have been idle for a prolonged period of time.
but this doesn't work for me as this should be fast game server. Putting code in thread or connecting client is out of question. I dont care if client gets the answer but one broken connection cannot block whole server. I dont know why but broken connection sends OP_READ key and this the killer. It has no data so read wait for incoming bytes blocking the loop.
Pleeeeeeese help?
Jarek