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

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.

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.

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 :)

Socket is closed on write stream but not when reading

I recently noticed in my multi threaded Java socket handler that I was getting exceptions when I tried to write on a socket, however I was still receiving data via reads. It was my understanding that if the socket was closed the input stream reader would also throw a socket closed exception when attempting the next read. Is this not the case and should I manually close the socket if I get this exception when attempting to write?
A TCP connection can be closed in the write direction but not in the read direction, such a connection is called "half closed". You should keep reading the rest of the data the other side sent, otherwise the connection will not close normally.
If you think about it, how else could you sanely shut down a TCP connection? If you shut it all the way down in one step, what happens if the other side sends some data to you before you finish shutting it down? You still need to receive it. But, obviously, you can't keep sending data.

Does closing the socket close the stream?

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.

Persistent I/O stream connection

I'm communicating with a server and ideally I would want an input stream and an output stream always up. I receive unsolicited responses, so I always have to be ready to receive data on the input stream.
Before I dive in much further, I should say that whatever connection I make must be capable of supporting SSL.
The problem I'm encountering is when I open an HttpUrLConnection and send stuff from the Output stream, it won't send the actual output until I open an input stream. If I open an input stream, it kills the output stream and there seems no was of recovering it once the stream is closed.
What would be the best way to implement my desired behavior? If maintaining both streams at once on one port is impossible, is there a way I could have two separate streams that share the connection via a sort of port lock/switch?
Is there a library for sending output without having to kill the output stream to signal the end of my request?
Http is a single request protocol.
You cannot (unless websocket) create a persistent connection using http(s). You need another protocol.
A basic socket can be used. It works mostly like an http connection except the url starts with socket://.
You simply open a connection, and then you can get the input stream and the output stream and use them.
- My best bet will be using the java.nio package.
- Use SocketChannel from java.nio package, we can set a SocketChannel into non-blocking mode. When you do so, you can call connect(), read() and write() in asynchronous mode.

Categories