Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should I use shutdown() before closing a socket? [duplicate]

Tags:

c++

sockets

On this MSDN page:

Sending and Receiving Data on the Client

It recommends closing the sending side of the socket by using:

shutdown(SOCK_ID, SD_SEND);

Why should I?

Maybe I dont have to, and its just a recommendation? Maybe its for saving memory? Maybe for speed?

Does anyone have an idea?

like image 683
fdwfg wdfwdfv Avatar asked Jan 25 '17 15:01

fdwfg wdfwdfv


People also ask

When would you use close vs shutdown on sockets?

In summary, use shutdown to send a shutdown sequence at the TCP level and use close to free up the resources used by the socket data structures in your process. If you haven't issued an explicit shutdown sequence by the time you call close then one is initiated for you.

What does socket shutdown do in Python?

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.

Which method is used to close the socket?

close() call shuts down the socket associated with the socket descriptor socket, and frees resources allocated to the socket. If socket refers to an open TCP connection, the connection is closed.

How do I shutdown a socket server?

You need to call shutdown() first and then close(), and shutdown takes an argument.


3 Answers

The answer is in the shutdown() documentation:

If the how parameter is SD_SEND, subsequent calls to the send function are disallowed. For TCP sockets, a FIN will be sent after all data is sent and acknowledged by the receiver.

...

To assure that all data is sent and received on a connected socket before it is closed, an application should use shutdown to close connection before calling closesocket. One method to wait for notification that the remote end has sent all its data and initiated a graceful disconnect uses the WSAEventSelect function as follows :

  1. Call WSAEventSelect to register for FD_CLOSE notification.
  2. Call shutdown with how=SD_SEND.
  3. When FD_CLOSE received, call the recv or WSARecv until the function completes with success and indicates that zero bytes were received. If SOCKET_ERROR is returned, then the graceful disconnect is not possible.
  4. Call closesocket.

Another method to wait for notification that the remote end has sent all its data and initiated a graceful disconnect uses overlapped receive calls follows :

  1. Call shutdown with how=SD_SEND.
  2. Call recv or WSARecv until the function completes with success and indicates zero bytes were received. If SOCKET_ERROR is returned, then the graceful disconnect is not possible.
  3. Call closesocket.

...

For more information, see the section on Graceful Shutdown, Linger Options, and Socket Closure.

In other words, at least for TCP, calling shutdown(SD_SEND) notifies the peer that you are done sending any more data, and that you will likely be closing your end of the connection soon. Preferably, the peer will also do the same courtesy for you. This way, both peers can know the connection was closed intentionally on both ends. This is known as a graceful disconnect, and not an abortive or abnormal disconnect.

By default, if you do not call shutdown(SD_SEND), closesocket() will attempt to perform a graceful shutdown for you UNLESS the socket's linger option is disabled. It is best not to rely on this behavior, you should always call shutdown() yourself before calling closesocket(), unless you have good reason not to.

like image 95
Remy Lebeau Avatar answered Oct 21 '22 19:10

Remy Lebeau


It is unnecessary and redundant except in the following cases:

  1. You want to achieve a synchronized close as described in the documentation quoted by Remy Lebeau.
  2. The socket has been duplicated somehow, e.g. it is shared with child or parent processes or via the API, and you want to ensure the FIN is sent now.
  3. Your application protocol requires that the peer receive a shutdown but needs to continue to send. This can arise for example when writing a proxy server.
  4. You may have unread data in your socket receive buffer and you want to close and ignore it and send a FIN before provoking a connection reset, which will happen when you close if there is unread pending data.

These are the only cases I've ever come across in about 30 years: there may be others but I'm not aware of them.

like image 33
user207421 Avatar answered Oct 21 '22 18:10

user207421


There are no specific resources associated with sending or receiving operation on the socket, the socket is either used or closed. There reason for shutdown is not related to resource-management. Shutting down the socket is implementation of so-called graceful shutdown protocol, which allow both sides of the communication to realize the connection is going down and allows to minimize loss of data.

like image 26
SergeyA Avatar answered Oct 21 '22 18:10

SergeyA