Does closing the socket close the stream? - java

I am working in a legacy java application, In many files, socket and streams are used, where sockets are getting closed but not the streams, is this necessary to close all the streams before closing the socket. because I am getting "too many open files error", is this error because of not closing the streams.....
closing the socket will automatically close the streams also?

From the Socket Javadoc:
Closing this socket will also close the socket's InputStream and OutputStream.
So generally speaking, closing the socket should be enough to close both streams it created.
Your "too many open files error" is most likely caused by something else.

Closing any one of those closes the other two, but you should close the outermost output stream (or Writer) that you have wrapped around the socket. That closes the input stream and the socket. If you don't close the outermost output stream yourself, it won't get flushed, and so you can lose data if there is a buffered outpput stream or writer in the stack. You could also close the socket itself in a finally block to be sure: in fact lack of finally blocks may well be the cause of your problem.

Related

Closing Sockets Procedure

In a TCP connection between sockets. What is the correct procedure to closing/shutting down the connection?
I have outputstreams, bufferedreaders and printwriters. Will closing the socket close all of them? Should they be closeds at both ends?(server and client)
You should close the outermost stream or writer you have wrapped around the socket output stream. That way it will get flushed if it is buffered.
Closing either the input or output stream or the socket closes everything else.
'Should they be closed at both ends?' doesn't really make sense. Sockets don't have two ends: connections do. The connection must be closed at both ends, but both ends have a socket, and all sockets must be closed.

Is Socket.close() considered a clean way to end the connection?

As the title says - if I want to close a socket connection is it enough if I just call mySocket.close()? What will happen on the other side?
Or, if it's not the way to go, what is? Do I have to send some kind of "finish" message through the socket so the other side knows it should end as well?
Bonus question: java documentations says
Closing this socket will also close the socket's InputStream and OutputStream.
So is closing the socket alone enough or do I have to explicitly close the streams as well (assuming I'm not using try-with-resources, of course)?
Closing the socket won't do any thing on the other side. The remote host will not know that the connection has been closed.
The only way to check whether the connection is closed is to try to read or write from/to the input/output stream. If -1 is returned by the InputStream#read() method, then the second side knows that the first side closed the connection. A thrown IOException also indicates a closed connection.
Normally you don't need to close the in/output stream as they are closed when invoking Socket#close(). Socket#close() is the only thing you need to do to close a connection.
But if you have a wrapper stream (e.g. BufferdInputStream/BufferedOutputStream) you should explicitly close these wrapper streams to release resources used by these wrapper streams (e.g. byte buffer array). You only need to close the top level wrapper stream as closing the wrapper closes the wrapped stream which closes the wrapped stream of the wrapped stream, too. And so on...
socket.close() is a clean way to close the connection. It causes a TCP FIN packet to be sent to the peer and starts the normal TCP shutdown sequence.
It also closes the socket's InputStream and OutputStream, I don't see any ambiguity in the documentation on that point.

Closing BufferedWriter/Reader affects other instances bound to the same socket?

I have 'n' server threads, and each one listen to 1 client.
When a server thread receives a message from its client, it needs to notify the other 'n-1' clients, and that's the reason why I keep a shared object (containing an array of 'n' sockets, one for each client) between the server threads.
Moreover, in the main server thread that holds the ServerSocket, every time I accept a new connection with a client I open a BufferedWriter/Reader to give a first answer to him using the new socket returned from ServerSocket.accept().
In case of an "OK" answer I open a new thread passing the new socket to it, in order to listen to the new client's following requests.
The problem is that i cannot close the BufferedReader and the BufferedWriter in the main server thread, because it will also close the underlying stream, causing problems to the server thread that is listening to that socket/stream.
And the question: if I open another BufferedReader (bound to the same socket) in the new thread, and then close it, will other BufferedReaders(Writers) ( specifically the ones opened in the main server thread, that i couldn't close before ) opened on the same socket be closed? Will an exception be thrown on them?
It could be possible to share the opened BufferedReader / Writer instead of the socket, to avoid instantiating every time a new object, but this is a question related to what could happen if i do things in the way described above.
Please tell me if I hadn't been clear, my english is not really good.
Closing any Reader or Writer or stream wrapped around a stream closes the wrapped stream.
Closing either the input stream or the output stream of a socket closes the other stream and the socket.
Closing the socket closes both streams.
In other words closing any of it closes all of it.
As noted in comments, multiple buffered streams/Readers/Writers wrapped around a single stream cannot work.
Multiple threads reading from/writing to the same socket is unlikely to work correctly either, unless you take great care with synchronization and buffering.
You should not do any I/O with an accepted socket in the accept loop. Otherwise you can block, which affects further clients.
You need to rethink your design.
Each Socket with an open connection to another Socket has an open InputStream and an open OutputStream. Closing either one of these streams will also close the socket. Closing a socket or its streams will not affect other sockets unless they are connected. You don't want to close any streams unless you also want to close the connection between the sockets using the streams. Please ask if there is something i missed or if you have other questions :)

Should Java streams be closed Before the backing socket is closed?

I have the following code:
public void disconnect()
{
running = false;
if(thread != null)
thread.interrupt();
thread = null;
try
{
socket.close();
}catch(Exception e){e.printStackTrace();}
}
I have a BufferedReader that collects the input from the stream and a PrintWriter that sends messages through the output stream. Should the BufferedReader and the PrintWriter be closed before i close the socket? Is it bad to leave the i/o streams open?
According to the Java Networking Tutorial
"You should close any streams connected to a socket before you close the socket itself."
You must close the output stream, so it gets flushed. That closes both the socket and the input stream. Closing any one of those closes the other two. You don't need to close the input stream at all. Strictly speaking for safety's sake you should probably also close the socket itself in a finally block.
If you don't close the BufferedWriter, you might lose some buffered but un-flushed data.
There's also a school of thought that says you shouldn't use PrintWriter, or to be careful if you do, because it swallows IOExceptions.
Every stream you open uses OS resources. When you call close on a stream it is marked for Garbage Collection and the memory is freed after GC. If you don't close the stream, it will be closed by GC (http://docs.oracle.com/javase/7/docs/api/java/io/FileInputStream.html#close%28%29) but it's not clear at all, when GC will hit that object.
So it's always better to close a stream to instantly free memory.

Properly closing Java Process InputStream from getInputStream

I could not find clarification of this in the documentation.
But when we have a Process object and call getInputStream(),
Do we get a new stream that we should explicitly close when we are done with it?
or
do we get the stream that is already there, associated with the Process, that we should not close, but the Process would take care of closing it?
Basically, how should we interact with the stream we get from Process.getInputStream()? close or not to close?
From reading UNIXProcess.java, this is what happens:
We need to distinguish between two states: either process is still alive, or it is dead.
If the process is alive, by closing OutputStream (goes to stdin of the process), you are telling the process that there is no more input for it. By closing InputStreams (stdout, stderr of the process), process is no longer to write to these (it will get SIGPIPE if it tries).
When process dies, Java will buffer remaining data from stdout/stderr, and close all three streams for you (it is running "process reaper" thread, which is notified on process death). Any attempt to write to OutputStream will fail. Reading from InputStream will return buffered data, if any. Closing any of them has no benefit, but also causes no harm. (Underlying file descriptors are closed by this time).
My first reactions was to close it, you always close streams that you open. I do realize the documentation is not up to par, but since they don't explicitly state do not close that to me means follow good programming practices.
InputStream is = process.getInputStream()
try {
// your code
} finally {
try { is.close(); } catch (Exception ignore) {}
}
If you need to make sure this isn't problematic, just write a quick test case where you great from the input stream a few dozen times, each time opening and closing the InputStream.
When you call Process.getInputStream() you get an existing input stream that was set up for the process. When the process dies, that input stream does not go away automatically - think of it as a buffer that you can still read from. The process's end of the pipe might be closed, but your end is not. It is your responsibility to close it, though GC will eventually get it.
You should also close the other two: getErrorStream() and getOutputStream().
You do not close streams, that you did not open - that's a nasty side effect.
If you created the process, kill it first and close streams after that.
I always close them! I am not 100% sure, but as far as I know if you leave the inputstream open, the file will be open until you close it!! So follow the "standard rules" and close it! follow an example:
Process Builder waitFor() issue and Open file limitations

Categories