Socket Shutdown: when should I use SocketShutdown.Both

Shutdown(SocketShutdown.Both) disables both the send and receive operations on the current socket. Calling Shutdown(SocketShutdown.Both) is an actual disconnection of your client from the server. You can see this by checking the socket Connected property in your SocketState object on the server side: it will be false.

This happens because the Shutdown operation is not reversible, so after stopping both send and receive on the socket, there's no point in keeping it connected as it is isolated.

"Once the shutdown function is called to disable send, receive, or both, there is no method to re-enable send or receive for the existing socket connection." (https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-shutdown)

As for your question:

  • I continuously send data to the client (via Send in a separate thread).
  • The client executed Shutdown(SocketShutdown.Both). --> this disconnects the client
  • The BeginReceive callback on the server executes, however, EndReceive throws an exception: An existing connection was forcibly closed by the remote host. This means that I am unable to receive the 0 return value and in turn call Shutdown.

EndReceive throws an exception because the client socket is not connected anymore.

To gracefully terminate the socket:

  1. the client socket calls Shutdown(SocketShutdown.Send)) but should keep receiving

  2. on the server, EndReceive returns 0 bytes read (the client signals there is no more data from its side)

  3. the server A) sends its last data B) calls Shutdown(SocketShutdown.Send)) C) calls Close on the socket, optionally with a timeout to allow the data to be read from the client

  4. the client A) reads the remaining data from the server and then receives 0 bytes (the server signals there is no more data from its side) B) calls Close on the socket

(https://docs.microsoft.com/it-it/windows/win32/winsock/graceful-shutdown-linger-options-and-socket-closure-2?redirectedfrom=MSDN)