views:

87

answers:

3

I have a java server that has to communicate over a TCP socket to an external program written in C. They pass messages back and forth in a message protocol that can't be changed (due to reasons too complicated to go into here).

The TCP messaging protocol looks roughly like this:

Header (with message length) -> Message body -> Message CRC

It seems to me like this is best handled on the java side with an ObjectInputStream/ObjectOutputStream pair and classes that implement java.io.Serializable and have their own writeObject() and readObject() methods. The problem is that the only solution I can think of for implementing this messaging protocol involves an extra level of indirection that I want to avoid if at all possible.

The diffculty is the write portion of the socket and comes because the message length is in front of the message body. My current solution is to write the message body to a secondary ObjectOutputStream (for the sole purpose of knowing the message length), then writing the header (with length) to the socket, followed by the body then the CRC.

My question is this: is there a better way to do this than to use the temporary ObjectOutputStream? That seems pretty wasteful.

Thanks.

A: 

If you know the maximum size of a message, I'd just give serious consideration to creating a byte array and having a method that writes the message directly into that, leaving space for the length.

Then, when you've written all the data bytes, go back and put in the length and calculate the CRC. Then you should be able to push the entire byte array (limited to the actual length) out to the oter end.

If you don't know the maximum size, you can use a vector or one of the other collections. It seems a larger-than-necessary effort to bring in all the serialisation stuff just to ship byte buffers around.

paxdiablo
Vector...? ByteArrayOutputStream is the right tool if you're going with this approach. You can layer an ObjectOutputStream on top of it, and then at the end you can use either the toByteArray or writeTo methods to get the data over to your socket.
Laurence Gonsalves
+2  A: 

Without more details I'd suggest that you shouldn't be using Object Streams at all they will serialize the Java object to a format that realistically can only been read back into a Java object. Your C program wouldn't really be able to do anything with what you send it.

You should probably just be using Byte Array Streams to send the kind of data that the C program can read. You would be able to read the length of the byte array to calculate the CRC.

William
A: 

Don't serialize objects (unless you want to mess with Externalization which you most likely don't).

Just generate the bytes instead, according to the specification and send them without making it more complex.

Thorbjørn Ravn Andersen