• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Rob Spoor
  • Tim Cooke
  • Junilu Lacar
Sheriffs:
  • Henry Wong
  • Liutauras Vilda
  • Jeanne Boyarsky
Saloon Keepers:
  • Jesse Silverman
  • Tim Holloway
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Mikalai Zaikin
  • Piet Souris

Socket InputStream available()

 
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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?
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Stan James
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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?
 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
Stan James
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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!
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic