BufferedReader problem with intermittant Socket reads and writes

I've tried searching around (and found useful information in these forums) but I can't seem to find anything on this exact problem...hopefully someone can give me a simple pointer in the right direction.

I'm trying to write a networked game, where a single server has multiple clients connected at once. The server spawns a new thread to handle a client each time a client connects, and that thread continues to run with the open socket for the lifetime of the client.

My problem is that while the socket remains open, I can't simply do something like the following (where inReader is a BufferedReader):

while(data = inReader.readline() != null) {

respondToData(data);

}

The reason is because I want to be able to send messages to the client independent of the client's state. For instance, if someone sends a message from another client directed to an idle user, I have a new message that needs to be sent to the client that's not simply a response.

What I was trying to do was something like this:

while(this.isFinished != true) {

if(inReader.ready()) {

// do readLine etc. here

}

// If there are messages that need to be sent, send one

if(!outgoingMessages.empty()) {

// send a message from the waiting outgoing messages queue

}

// Sleep for a little here if we haven't done work this cycle

// to avoid burning so much CPU

}

From the documentation, .ready() apparently only returns true if .read() is guaranteed to not block, NOT .readLine(). Is this correct? Regardless, I'm hoping it should work okay for me since all of my data should be in the form of single-line messages.

Unfortunately, .ready() apparently returns false if the end of stream has been reached (if the remote client disconnects rudely without saying bye, for instance). The result of this is that the while loop never realizes the client is gone. I don't know a way to check this without doing a .readLine and seeing if it returns null, but that would mean I run the risk of blocking, and if I do that, I can't send arbitrarily timed messages to the client.

Quite possibly, I'm doing something with bad style or bad design here, so please tell me if that's the case. :p

[2291 byte] By [GTSchemera] at [2007-11-27 8:05:11]
# 1
You need separate threads for reading and writing per client, or else you need to plunge into the heady world of non-blocking multiplexed I/O via java.nio.channels.
ejpa at 2007-7-12 19:47:42 > top of Java-index,Core,Core APIs...
# 2

I didn't know if I could do a write if I was blocking while reading for the same socket.

I guess they're separate writer/reader objects, so it'd make sense...

The solution I think I have reached (at least for now) is to add a time variable that records the last known time the client was alive. Since (according to my protocol) each client is supposed to send a keep-alive message every 5 seconds or so, I can simply drop the client after not receiving any messages from them for 10 seconds.

Thanks a lot, though! I didn't know anything about channels or java.nio.channels, and someone else linked me to http://www.kegel.com/c10k.html which has some interesting possibilities for massive numbers of clients (which I hopefully won't have to deal with).

GTSchemera at 2007-7-12 19:47:42 > top of Java-index,Core,Core APIs...