What is the difference between closing Input/OutputStream and closing Socket directly?

17,043

Solution 1

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.

Solution 2

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.

Solution 3

This is more like a comment than a good answer: (I would rather add a comment to one the answers above but I don't have the rep)

The question, as I read it, is "can I close a stream on a socket and then open a stream on the same socket?"... but people seem to be answering this: "how should I cleanly close my socket?"... which is not the question being asked.

The answer to the question being asked is "no". When you close the stream, you close the socket.

(I do understand why, in at least one case, someone might ask this question. When you are streaming Java Properties over a socket the receiving end has to see EOF to recognize the end of the properties - for the receiver to see EOF the sender has to close the stream/socket. BUT, if you have a command/response protocol operating over that socket, you DON'T want to close it or you'll lose the channel that you want to send a response on. See Java streaming Properties over Socket for one way to handle this)

Share:
17,043
Alfred
Author by

Alfred

I am a programmer and interested in algorithms and software and system design.

Updated on June 23, 2022

Comments

  • Alfred
    Alfred almost 2 years

    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!

  • irreputable
    irreputable over 13 years
    closing the output stream == closing the socket. flush+fin might not be done as in shutdownOutput
  • user207421
    user207421 over 13 years
    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.
  • irreputable
    irreputable over 13 years
    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.
  • user207421
    user207421 over 13 years
    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.
  • Pacerier
    Pacerier almost 12 years
    So you are saying InputStream.close calls Socket.close, which in turn calls InputStream.close, which in turn calls Socket.close, which in turn calls InputStream.close..... ?
  • Jes
    Jes over 11 years
    A socket is closed when the streams are closed. If you call InputStream.close and try to read from the socket, it will throw an exception. Socket.close closes the input and outputstreams of the socket, calling close on the individual streams does not call Socket.close, but will still result in a closed socket.
  • user207421
    user207421 over 11 years
    Certainly it calls Socket.close(). The infinite regression is avoided by a 'closing' flag.
  • user207421
    user207421 over 10 years
    Your concept of closing and then reopening a socket and expecting it to remain connected is meaningless.
  • PMorganCA
    PMorganCA over 10 years
    @EJP I don't think your comment is helpful or fair. The "concept" is not mine, it's implied by the asker of the question. If you read my answer more carefully you would have seen I know you cannot close and then reopen a socket. I've reworded my answer so it's easier to get my point.