I'm writing a little special-purpose HTTP server. It does stuff like this:
On my NT machine everything is beautiful. But! On my Win98 machine available() returns 0 on perfectly GET messages. This loop never reads anything, I get empty strings for the expected HTTP headers, exceptions ensue. I can hit refresh on the browser a half dozen times and finally get the page. POST messages may be even worse - I didn't actually count. I moved the test for available()>0 to after the first read and the Win98 machine works fine. Anybody know any tricks dealing with this input stream? Maybe a conflict with ZoneAlarm or some other program on my system?
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
The available() method is always allowed to return a number smaller than the remaining message size. Generally it tells you how many of the bytes have been read into an internal buffer somewhere (thus, how many bytes can be read immediately without blocking). As a result, the available() method is really not good for much. You can use it to avoid blocking reads, but then you lose your ability to detect and EOF, because when you get to the end avilable() == 0, and you can't know if it's a real EOF or just a network delay until you do a read() and get the -1 indicating EOF. Or block indefinitely if it's not an EOF. Anyway, I think the best solution is to forget available() and just read:
You need to keep waiting for input until \n or EOF, right? You can of course improve efficiency by wrapping in a BufferedReader if you didn't already. The downside of this method is that if you're waiting for input from many different sources (e.g. a chat server waiting for any of its many users to type something, most of whom are dormant at any given point in time) then it's a bit ineffecient to devote a whole thread to a blocking read() call, waiting for more input from one user. If this is an issue, look into using a Selector from NIO to allow oone thread to listen to a bunch of channels at once, and, whenever something comes in, hand the data off to another worker thread for processing.
"I'm not back." - Bill Harding, Twister
Joined: Jan 29, 2003
Thanks, your info on available() was just what I needed. It's outta there! I lifted some logic from the famous OReilly MultiPartParser for handling file uploads. He's reading from a ServletInputStream. I wonder if it pre-reads or something to make available() more reliable?
Joined: Jan 30, 2000
Um, where is this exactly? I couldn't find available() used this way in any of the com.oreilly.servlet code available here. Perhaps you're looking at an older version, a bug that has now been fixed? Misuse of available() is not uncommon even among experts. (Even Doug Lea fell victim in Concurrent Programming in Java, see here.) There's a tendency to assume that, since they put the method inthe API, it's actually useful for something. In most cases, it isn't. It was an attempt at facilitating nonblocking IO, but to do that right we really need the NIO classes. [ October 08, 2003: Message edited by: Jim Yingst ]
Joined: Jan 29, 2003
Hmmm, I remembered available() as the condition for a loop, but don't see it now. It is used in PartInputStream but not quite that blatantly. Maybe I made that up!