tags:

views:

170

answers:

3
+3  Q: 

Close java socket

I just wondering what java does when we call close on the inputStream and outStream associated with a socket. What is the difference from the close call on the socket, i.e Socket.close().

if we just close the io stream on the socket, but not close the socket, can we reopen the io stream on the socket again?

Thanks in advance!

+2  A: 

From the java api documentation for Socket:

public void close() throws IOException Closes this socket. Any thread currently blocked in an I/O operation upon this socket will throw a SocketException.

Once a socket has been closed, it is not available for further networking use (i.e. can't be reconnected or rebound). A new socket needs to be created.

Closing this socket will also close the socket's InputStream and OutputStream.

If this socket has an associated channel then the channel is closed as well.

Closing the InputStream of the Socket will lead to the closing of the Socket. The same goes for closing the OutputStream of the Socket.

From the java api documentation for Socket#getInputStream()

Closing the returned InputStream will close the associated socket.

Check the API documentation, it is there for a reason.

Jes
A: 

Generally, close() should only be done by the party responsible for open(). That way, the open-close pair can be managed easier. Since we can't open socket i/o streams (conceptually they are open as soon as socket is open), we should not close them. The party that opened the socket should close the socket though.

Sometimes you have no choice, you pass an open stream to a method, and the method decides it has the right to close the stream. You can pass a wrapper stream so that close() doesn't have effect.

If you really want to, you can close socket i/o streams without closing the socket, but they cannot be re-open once closed.

shutdownInput() - pretty useless. If an application doesn't need any more input, simply stop reading - there is no point to invoke this method. Stop receiving data from peer. If the peer tries to send data to us, it may receive error ("connection reset")

shutdownOutput() - can be very useful, it flushes all the data to the peer, and sends a FIN signal. The connection is now half-closed. The peer can still send data, and we can still read it, because that direction is still open.

These two methods are not used often. Normally Socket.close() is called to end the whole connection.

irreputable
Several mistakes there, see my reply. Specifically it is far from 'normal' to call Socket.close(): in most cases it is actually incorrect.
EJP
+1  A: 

You should close the outermost output stream you have created from the socket. That will flush it. Closing either the socket or the input stream doesn't do that so it isn't adequate. Having closed that output stream you don't need to do anything else.

EJP
closing the output stream == closing the socket. flush+fin might not be done as in shutdownOutput
irreputable
That is entirely incorrect. Closing the output stream flushes the *stream* if necessary (see the FilterOutputStream.close()) and then closes both it and the socket. Closing the socket *or* calling shutdownOutput *doesn't* flush the socket (i.e. its send buffer), it just queues a FIN at the end of the current socket send buffer. What happens after that is asynchronous to the closing process, unless it has set a positive 'linger' timeout.
EJP
Am I on a different internet than yours? Read the javadoc. `shutdownOutput` - "any previously written data will be sent followed by TCP's normal connection termination sequence" `getOutputStream` - "Closing the returned OutputStream will close the associated socket" `close` - says nothing about flush and FIN.
irreputable
Of course they will be sent. They're in the send buffer. That's what it's for. But they aren't *flushed* by calling shutdownOutput(), as you claimed, they would have been sent anyway, and there is no guarantee that they have been sent when shutdownOutput() returns. And you've completely missed my point about closing the *outermost* output stream, which might be a buffered output stream, or a stream wrapped around one. If you don't close that, it won't be flushed. And closing the socket by any means sends a FIN.
EJP