tags:

views:

1807

answers:

4

I have an application that uses simple sockets to pass some characters between two systems. I have my java application running as a server. I establish a connection fine, and even pass one message. However, after one message has been sent my connection closes.

From what I can tell it appears as if on closing the printWriter and bufferedReader the socket itself is being closed?! This is bad, as I have multiple messages to send on the same connection.

            printWriter = new PrintWriter(theServer.getClientSocket().getOutputStream());
   bufferedReader = new BufferedReader(new InputStreamReader(theServer.getClientSocket().getInputStream()));


   printWriter.println("the line");

   printWriter.close(); //Closing on these lines?
   bufferedReader.close(); //Closing on these lines?

Am I full of it? How do I maintain this connection in Java?

+5  A: 

Yes, closing any Writer/Reader will close all other Writers and Readers that they wrap. Don't close it until you are ready to close the underlying socket.

Eddie
Do I need to flush the buffers then? Can I just leave those lines out and keep using the socket per the code above?
windfinder
You will need to flush if you want to control when the lines hit the wire.
Darron
Flushing works... gracious kind sirs...
windfinder
Close is an implicit flush. If you want to flush before you call close, then by all means, call flush.
Eddie
+1  A: 

As @Eddie said (seconds before me! :) ), closing the writer and/or the reader will close the underlying socket streams. However, I believe the socket itself will not be closed.

You shouldn't close the writer nor the reader. Just flush the writer to make sure your messages will arrive in time. Closing the socket later on will close the respective streams, so you don't need to close them yourself. Just leave your reader/writer objects to the GC.

Hosam Aly
A: 

You need to close the socket after closing the streams.

Peter Lawrey
A: 

Another alternative is to create yourself a NoCloseInputStream and NoCloseOutputStream filters which simply do nothing on close; then use them to wrap your application socket's streams (before any application wrappering like a buffer).

Note that if you were to do this, you would need to keep a reference to the socket (or the wrapped streams) so that you can close the socket when you are actually done with it.

To answer the comment that this is "too advanced a concept for the OP": The OP's problem is that in closing the top level stream, he is also closing the underlying socket, but that's no good since he want to create further top-level streams over the socket to send further messages. Depending on his architecture, the only way to achieve this may be to wrap the streams in NoClose wrappers - for example he may be passing the streams to an XML serializer or deserializer which closes the stream when it's done, which close is outside of his control.

Software Monkey
I believe this answer is too advanced for the question. It can only confuse the OP in my opinion.
Hosam Aly