Search code examples
javasocketsinputstreamoutputstreamtcpsocket

How to close a Java's socket's outputstream while keeping the inputstream open to get a result?


I'm sending a message to a server, which passes correctly.

But, when trying to read the result, I get an exception that the Socket is closed.

Any idea how to close the socket's outputstream while keeping the socket and socket's inputstream open to get the result?

Client code:

Socket socket = new Socket("localhost", 9090);
String message = "Some message";
new OutputStreamWriter(socket.getOutputStream(), Charsets.UTF_8)
        .append(message)
        .close();
// The following line throws the exception when socket.getInputStream() is called:
String fromServer = CharStreams.toString(new InputStreamReader(socket.getInputStream(), Charsets.UTF_8));

Exception:

java.net.SocketException: Socket is closed

    at java.net.Socket.getInputStream(Socket.java:903)
    at alik.server.test.Client.pingServer(Client.java:24)

Solution

  • From the javadoc of Socket.getOutputStream():

    Closing the returned OutputStream will close the associated socket.

    In other words, don't close the output stream until you are done with the input stream. Closing the input stream will also close the socket (and as a result, also the output stream).

    You could use Socket.shutdownOutput() to prevent further writing to the socket, but I don't really see the point of using that, and it could result in the peer closing its socket prematurely, as Stephen C explains in the comments:

    The peer should only see the closed stream if it reads. What happens next will depend on how it responds to seeing the closed stream.