ObjectInputStream available() method

G

Guest

I have a servlet-applet couple which communicate via a server Socket and
client Socket couple. In the functioning implementation the servlet
listens on the ServerSocket, opens a clientSocket when the applet
connects, and opens onto it two streams. The applet does the same on its
side.

PrintWriter appletout = new
PrintWriter(mySocket.getOutputStream(), true);
BufferedReader appletin = new BufferedReader(new
InputStreamReader(mySocket.getInputStream()));

The applet tests appletin.ready() before reading with
appletin.readLine(). In some cases it has to test a few times before it
becomes ready, but it works.

Now I want to write a DIFFERENT servlet-applet couple, which exchanges
some complex binary data.

In this case on the servlet side I thought I should have an
ObjectOutputStream

appletout = new ObjectOutputStream(clientSocket.getOutputStream()) ;

and on the applet side I should have

appletin = new ObjectInputStream(mySocket.getInputStream() );

I expected that, in order to test that the stream is ready, I had to
replace the ready() call with a appletin.available() != 0

It occurs instead that this is not true, apparently (I'm currently
testing between two standalone applications) available() always returns
zero, and the pseudo-applet can immediately issue a

s = (String) appletin.readObject() ;

as soon as the pseudo-servlet has e.g. issued

appletout.writeObject((String) "READY");
appletout.flush();

(is my assumption that each write shall be immediately followed by a
flush ?)

How does one use available() or any other way to find that there is
pending data on the input channel ?
 
O

Owen Jacobson

I have a servlet-applet couple which communicate via a server Socket and
client Socket couple. In the functioning implementation the servlet
listens on the ServerSocket, opens a clientSocket when the applet
connects, and opens onto it two streams. The applet does the same on its
side.

PrintWriter appletout = new
  PrintWriter(mySocket.getOutputStream(), true);
BufferedReader appletin = new BufferedReader(new
  InputStreamReader(mySocket.getInputStream()));

The applet tests appletin.ready() before reading with
appletin.readLine(). In some cases it has to test a few times before it
becomes ready, but it works.

What does it do if it discovers the stream is *not* ready()? If it
waits, you're doing exactly what would happen if you skipped the
ready() check, but at a higher cost in CPU power. If you're trying to
avoid blocking another ongoing task (like the Swing EDT), you may be
better off doing the IO on a background thread via something like
SwingWorker.

The only reliable way to test whether a stream has data ready or not
is by reading it. All else is inaccurate and underinformative. In
particular, the available() method almost universally returns zero,
except for BufferedInputStreams with data buffered up. Similarly,
ready() may "lie" if the amount of data available without blocking is
insufficient to rebuild the entire object graph -- in which case
readObject() will block waiting for the rest of the data.

-o
 
D

Daniel Pitts

LC's No-Spam Newsreading account said:
How does one use available() or any other way to find that there is
pending data on the input channel ?

From the javadocs:
Returns the number of bytes that can be read (or skipped over) from this input stream without blocking by the next caller of a method for this input stream. The next caller might be the same thread or another thread.

The available method for class InputStream always returns 0.

What this means to me is that available tells you the largest number of
bytes that you can read/write without worrying about blocking. You may
be able to read/write more.

Anyway, in your situation, I would suggest having a thread for the
reading, and fire off an event when a new object comes through. That way
it is okay for the read calls to block, and you don't have to worry
about readiness/availability of data.

Hope this helps,
Daniel.
 
A

Arne Vajhøj

LC's No-Spam Newsreading account said:
I have a servlet-applet couple which communicate via a server Socket and
client Socket couple. In the functioning implementation the servlet
listens on the ServerSocket, opens a clientSocket when the applet
connects, and opens onto it two streams. The applet does the same on its
side.

PrintWriter appletout = new
PrintWriter(mySocket.getOutputStream(), true);
BufferedReader appletin = new BufferedReader(new
InputStreamReader(mySocket.getInputStream()));

The applet tests appletin.ready() before reading with
appletin.readLine(). In some cases it has to test a few times before it
becomes ready, but it works.

Now I want to write a DIFFERENT servlet-applet couple, which exchanges
some complex binary data.

In this case on the servlet side I thought I should have an
ObjectOutputStream

appletout = new ObjectOutputStream(clientSocket.getOutputStream()) ;

and on the applet side I should have

appletin = new ObjectInputStream(mySocket.getInputStream() );

I expected that, in order to test that the stream is ready, I had to
replace the ready() call with a appletin.available() != 0

It occurs instead that this is not true, apparently (I'm currently
testing between two standalone applications) available() always returns
zero, and the pseudo-applet can immediately issue a

s = (String) appletin.readObject() ;

as soon as the pseudo-servlet has e.g. issued

appletout.writeObject((String) "READY");
appletout.flush();

(is my assumption that each write shall be immediately followed by a
flush ?)

How does one use available() or any other way to find that there is
pending data on the input channel ?

I will recommend avoiding .available() and .ready() completely.

Just read, use exception or return value to detect EOF, and if
you need not to block the thread, then make a blocking read
in a separate thread.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,737
Latest member
Georgeengab

Latest Threads

Top