Non-blocking blocking I/O?

[quote]I have a “not-so-off-topic” question:
Many people claim, that prior to JDK 1.4.0 all IO operations were blocking and there was no way to avoid thread-per-client model. This I cannot really understand, because:
[/quote]
The only way around this was to use JNI. There were a few asynch/NIO alternatives before 1.4, at least one of which was a major influence on 1.4’s design.

Read the javadocs for it. InputStream always returns 0 for this method. Do you see a problem :slight_smile: ?

BufferedInputStream simply returns 0 + however many extra bytes it has accidentally read in on the last read and not surrendered yet.

I’m afraid I can’t give you a definite answer, because it’s so long since I was using I/O, but off the top of my head the available method either returned 0 or “guessed” (this was a known problem and I have a vague memory that Sun used to say it was a “guideline” figure rather than necessarily accurate, because I/O wasn’t attempting to provided non-blocking capability).

IIRC this is another example of where the general API allows you to try to do something that a particular implementation won’t - InputStream was NOT designed just for networking, and some of it’s subclasses can actually return a sensible value for available (not to mention that you want the method in the superclass for type reasons)…but that doesn’t mean that just because you have an object of that type and that the method exists that the method will actually be valid in that situation.

So, you could call this method, but it had no meaning.

Some of us believe this is a fatal flaw in Sun’s API design - it cannot throw an exception because it actually doesn’t transmit data, it just shunts it onto a queue and then when that data fails it can’t get a notification because the API doesn’t have callbacks. IIRC a JVM engineer told us that you would get the IOE on the NEXT call to the method, which is insane and stupid and I have trouble believing.

Go to JGF (link in my signature below), go to the articles section, and read the NIO articles. That should convince you…

[quote]So, you could call this method, but it had no meaning.
[/quote]
I have read relevant javadoc many times :wink: InputStream.available() is really said to return 0, but it is an abstract class. If you call Socket.getInpustStream() you will get an instance, which behaves correctly. I have tried it today with both 1.3.1 and 1.4.1 (from sun for ms windows) and it seems to works fine. As I said before, I have programmed multiplayer game using this approach, and it works more then just fine.

[quote]Some of us believe this is a fatal flaw in Sun’s API design - it cannot throw an exception because it actually doesn’t transmit data, it just shunts it onto a queue and then when that data fails it can’t get a notification because the API doesn’t have callbacks. IIRC a JVM engineer told us that you would get the IOE on the NEXT call to the method, which is insane and stupid and I have trouble believing.
[/quote]
I myself am quite happy with this behavior of “write”. I don’t mind that write doesn’t provide feedback, because if anything went wrong, I will learn about it when I call available() or read(). They will throw an exception. I do this at the beginning of each “heartbeat” - so I learn about broken connection fast.
My algoritm is very simple:

while (true)
{
checkForNewConnections();
// I have separated ‘connector’ thread for this
checkForNewMessages(); // using available & read
processMessages();
createStatusUpdateMessage();
sendStatusUpdateMessageToClients();
sleep(~500ms);
}

the only problem is, that in extremely bad case (when message is delivered just after checkForNewMessages) it takes 2 heartbeats before response is sent. I think that this could be improved with NIO.

I have read all your articles yesterday, while reading TCP vs UDP thread :slight_smile: They are really extremely helpful, good work. I think I will definitely try to implement it with NIO… and… I will see :slight_smile:

I will confirm Matlu’s statement about using Socket.getInputStream’s available(). I have used it many times in the past to do “non-blocking” IO with standard IO. It works very well in a game environment since you have a polling situation (you just check it every pass though the game loop). It’s a serious pain in the butt when you don’t (e.g. most enterprise applications).