tags:

views:

150

answers:

2

I have a Java server that accepts SSL connections using JSSE and uses a simple XML message format inside the stream. I would like the server to read a complete message and then send a reply. This turns out to be quite difficult because org.xml.sax.XMLReader wants to read the entire stream and then call close(). I know it seems strange, but in Java 6 with the Sun JSSE provider this really does close both ends of the SSLSocket so no message can go back. I tried using the shutdownOutput() method of Socket on the client side, but this is unsupported with JSSE.

My solution was to pass an InputStream wrapped in a custom class that silently ignores close requests and indicates that the stream is closed when it encounters the first blank line. This constrains the XML beyond what is normally valid, but the client can easily filter out blank lines in the input if necessary. Is there a better solution?

+1  A: 

How does your client know when a complete message has been read? If it has to read until the input stream reaches its end, then, by definition, you won't be able to read anything from the stream afterwards anyway. On a second note, invoking close() on the input stream shouldn't be closing the socket. Are you sure that the socket is closed when you call close() on the input stream? May be the connection is (incorrectly) closed by the peer when it notices that its output stream (your input stream) has been closed.

A solution that avoids reading until the end of the input stream is to delimit the input message somehow. For example, you could send the length of the message before the message, then read the whole message from the stream into a buffer, then parse the buffer using XMLReader, or create a special InputStream that takes that reaches its end after the specified amount of data. Or you could add a special delimiter in the stream after the message, then you'd create a special InputStream reaches its end when the underlying stream produces the delimiter.

Alexander
+1  A: 

Since each xml document has only one root node. So, scan the end of this node and close the stream after.