socket.shutdown vs socket.close

200,071

Solution 1

Here's one explanation:

Once a socket is no longer required, the calling program can discard the socket by applying a close subroutine to the socket descriptor. If a reliable delivery socket has data associated with it when a close takes place, the system continues to attempt data transfer. However, if the data is still undelivered, the system discards the data. Should the application program have no use for any pending data, it can use the shutdown subroutine on the socket prior to closing it.

Solution 2

Calling close and shutdown have two different effects on the underlying socket.

The first thing to point out is that the socket is a resource in the underlying OS and multiple processes can have a handle for the same underlying socket.

When you call close it decrements the handle count by one and if the handle count has reached zero then the socket and associated connection goes through the normal close procedure (effectively sending a FIN / EOF to the peer) and the socket is deallocated.

The thing to pay attention to here is that if the handle count does not reach zero because another process still has a handle to the socket then the connection is not closed and the socket is not deallocated.

On the other hand calling shutdown for reading and writing closes the underlying connection and sends a FIN / EOF to the peer regardless of how many processes have handles to the socket. However, it does not deallocate the socket and you still need to call close afterward.

Solution 3

Explanation of shutdown and close: Graceful shutdown (msdn)

Shutdown (in your case) indicates to the other end of the connection there is no further intention to read from or write to the socket. Then close frees up any memory associated with the socket.

Omitting shutdown may cause the socket to linger in the OSs stack until the connection has been closed gracefully.

IMO the names 'shutdown' and 'close' are misleading, 'close' and 'destroy' would emphasise their differences.

Solution 4

it's mentioned right in the Socket Programming HOWTO (py2/py3)

Disconnecting

Strictly speaking, you’re supposed to use shutdown on a socket before you close it. The shutdown is an advisory to the socket at the other end. Depending on the argument you pass it, it can mean “I’m not going to send anymore, but I’ll still listen”, or “I’m not listening, good riddance!”. Most socket libraries, however, are so used to programmers neglecting to use this piece of etiquette that normally a close is the same as shutdown(); close(). So in most situations, an explicit shutdown is not needed.

...

Solution 5

Isn't this code above wrong?

The close call directly after the shutdown call might make the kernel discard all outgoing buffers anyway.

According to http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable one needs to wait between the shutdown and the close until read returns 0.

Share:
200,071

Related videos on Youtube

Jason Baker
Author by

Jason Baker

I'm a developer on Google's Cloud Console.

Updated on July 08, 2020

Comments

  • Jason Baker
    Jason Baker almost 4 years

    I recently saw a bit of code that looked like this (with sock being a socket object of course):

    sock.shutdown(socket.SHUT_RDWR)
    sock.close()
    

    What exactly is the purpose of calling shutdown on the socket and then closing it? If it makes a difference, this socket is being used for non-blocking IO.

  • Matt Joiner
    Matt Joiner over 14 years
    great answer, i never bothered to find out what shutdown() does :)
  • ernesto
    ernesto over 10 years
    Can a shutdown() for read causes it to send a FIN packet? i.e. shutdown(sock_fd, 1);
  • Luc
    Luc about 10 years
    Would it be smart to always call .shutdown() and on the next line .close()? Or should there be a delay in between?
  • Robert S. Barnes
    Robert S. Barnes about 10 years
    @Luc Completely depends on what you're doing.
  • Luc
    Luc about 10 years
    @RobertS.Barnes I just want to get rid of the connection. Send a FIN and disallocate the RAM.
  • Robert S. Barnes
    Robert S. Barnes about 10 years
    @Luc Then just close is fine as long as no other processes have a handle to the socket.
  • user207421
    user207421 over 4 years
    It does not indicate to the other end that there is no further intention to read. Shutdown for read doesn't send anything to the peer.
  • user207421
    user207421 over 4 years
    This information isn't correct. It is only ever necessary to shutdown a socket for writing if (1) you have forked the process and definitely want to send the FIN now, or (2) you are engaging in a mutual read-to-EOS protocol such that both peers close at the same time. Otherwise close() is sufficient. The Python documentation should be corrected.
  • user207421
    user207421 over 4 years
    Not correct. The kernel will only discard outgoing buffers if the connection has been reset, which can happen if the local app hasn't read all the pending inbound data that has already arrived, or if the peer has messed with SO_LINGER, which they shouldn't do. There is no necessity to sleep either, nor even to call shutdown before close. There is a lot of misinformation out there about this matter.
  • user207421
    user207421 over 4 years
    There is one 'flavour' of shutdown, and it has two options, which can be combined. Nothing here answers the actual question.
  • user207421
    user207421 over 4 years
    Shutdown does not force a flush. The buffering situation is unchanged. And if the buffer isn't empty no error is raised. The FIN is merely enqueued behind the pending data. Answer is completely incorrect.