Reputation: 36001
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)
Upvotes: 2
Views: 3828
Reputation: 310885
You can't. Closing a socket input or output stream closes the other stream and the socket.
However the real problem here is that the peer is trying to read until end of stream before it sends anything back. This is an applicaton protocol issue. You could overcome it by shutting down the sending socket for output after sending everything that is to be sent, as mentioned by @MarkRotteveel, but this restricts you to one request/response per connection.
It would be better to review your application protocol to discover how the peer can know where the end of a request is, and only read that far before replying. For example, possibly you should be sending lines.
Upvotes: -1
Reputation: 108982
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.
Upvotes: 11
Reputation: 406
As mentioned by Joseph, I don't think you should close the OutputStream before opening the InputStream.
According to Oracle Docs (https://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html), the correct order is:
- Open a socket.
- Open an input stream and output stream to the socket.
- Read from and write to the stream according to the server's protocol.
- Close the streams.
- Close the socket.
Upvotes: 1
Reputation: 118
You can't close an OutputStream without closing the socket(See two links below). Is there a specific reason why you need to do this?
You would need to finish read/writing before you close the socket and it's input/output streams.
Returns an output stream for this socket.
If this socket has an associated channel then the resulting output stream delegates all of its operations to the channel. If the channel is in non-blocking mode then the output stream's write operations will throw an IllegalBlockingModeException.
Closing the returned OutputStream will close the associated socket.
Behavior of Java sockets when closing output stream
https://docs.oracle.com/javase/7/docs/api/java/net/Socket.html#getOutputStream()
Upvotes: 2