Sending mixed Serialized and non serialized data

I'm using a network socket and sending mixed Serialized data and non serialized data. That is at first there is a non-serialized set of chars as a text stream using a PrintStream, then I attach a ObjectOutputStream to the underlying OutputStream and send serialized binary Object, then I switch back to using the PrintStream for sending text data (another header). This is all properly synchronized on both ends of the socket (i.e. PrintStrean-->Reader and ObjectOutputStream-->ObjectInputStream, and again both are using the same instance of Socket.getOutputStream())

It all works with the following exception. After using the PrintStream I have to delay writting anything into the ObjectOutputStream by about 200ms. Any value smaller then 200ms causes various exception (EOFStream, StreamCorruptedException, etc.) on the receiver end of the ObjectInputStream (on another system.)

I've tried flushing the stream and no effect.

This was hard to track down since it would get invalid stream under normal VM (undebugged) and then magically everything works when ran under the debugger.

Does ObjectOutputStream use some kind of worker thread that needs to catch up? Is there a way to synchronize or block on this condition without resorting to Thread.sleep(200)?

I'm using Java 5.0 envinroment.

[1339 byte] By [voytechsa] at [2007-10-2 14:56:41]
# 1
> I've tried flushing the stream and no effect. That was my first thought.Which stream exactly did you flush?
jverda at 2007-7-13 13:39:30 > top of Java-index,Core,Core APIs...
# 2

I flush them backward. That is the

1st) ObjectOutputStream

2nd) PrintStream

3rd) The common OutputStream

No effect.

As a test, I even tried closing the ObjectOutputStream, forcing all the data to be written out. Did not have the desired effect.

I should add, that the PrintStream data is delivered immediately and properly. Only the ObjectOutputStream is having trouble without that delay.

voytechsa at 2007-7-13 13:39:30 > top of Java-index,Core,Core APIs...
# 3
OOS has a method--reset() or something I think--that's used to flush out cached data that it maintains to avoid sending multiple copies of the same object. Maybe try that?
jverda at 2007-7-13 13:39:30 > top of Java-index,Core,Core APIs...
# 4

It is happening on the first instance of an Object I'm sending. Plus I did try the reset while testing. No effect. I also tried close() on the stream.

Its as if the ObjectOutputStream data written is simply dropped by either the ObjectOutputStream or the underlying OutputStream. After that 200ms dealy everything works normal.

I'm thinking that because this is a network socket, some kind of timing contention?

voytechsa at 2007-7-13 13:39:30 > top of Java-index,Core,Core APIs...
# 5

No idea. I don't really know about the innards of streams and sockets. I would think it would be okay to share the stream like that, if you're careful and if the stream/writer/socket classes in question are solid. But I'm not terribly surprised that it doesn't work--or doesn't work as easily as you might hope.

jverda at 2007-7-13 13:39:30 > top of Java-index,Core,Core APIs...
# 6
Everything works fine without using delay when I only use ObjectOutputStream and not use PrintStream to write the text header. This is as expected.
voytechsa at 2007-7-13 13:39:30 > top of Java-index,Core,Core APIs...
# 7

You can use both, but you need to stack them one on top of the other, i.e.:

BufferedOutputSteam bos = socket.getOutputStream();

PrintStream ps = new PrintStream(bos);

ObjectOutputStream oos = new ObjectOutputStream(ps);

or the other way around, and always flush the last one created after you switch from writing to it to writing to the other one.

ejpa at 2007-7-13 13:39:30 > top of Java-index,Core,Core APIs...
# 8

I'd be looking at the input side of this. Is there a buffered stream that is not shared by the ObjectInputStream? If there is then the symptoms can be explained. A buffered stream will read in as much data as is available (up to some limit), regardless of whether that data is required. If you switch to the ObjectInputStream before the data has been consumed, then it has effectively been lost.

The 200ms delay prevents the buffered stream from consuming the extra, and makes the program work.

The solution is to ensure that the ObjectInputStream shares the buffered stream.

Sylvia.

sylviaea at 2007-7-13 13:39:30 > top of Java-index,Core,Core APIs...