2

I'm using a TcpClient and calling Close when I want to drop the client's connection to my server. My understanding is that Close will call Shutdown on the socket if it hasn't already been called.

Can anyone explain what "terminated" means in the context below? From what I've observered, it means that the party that calls Shutdown will send a hard reset (RST) rather than going through the graceful shutdown sequence (FIN, ACK...).

From: https://msdn.microsoft.com/en-us/library/system.net.sockets.socket.shutdown(v=vs.110).aspx

Setting how to Receive specifies that subsequent calls to Receive are not allowed. This has no effect on lower protocol layers. If you are using a connection-oriented protocol, the connection is terminated if either of the following conditions exist after a call to Shutdown :

  • Data is in the incoming network buffer waiting to be received.
  • More data has arrived.

Based on this, if I wanted to do a graceful shutdown I must try to empty my local receiving buffer before calling Close.

Is that right or is there a way to guarantee a graceful shutdown occurs?

3
  • Shutdown causes a graceful shutdown. This is the preferred way. Not shutting down often also ends up in a graceful shutdown but errors are not reported. Commented Aug 12, 2015 at 21:36
  • I think this answers your question,from a Windows perspective: Graceful Shutdown, Linger. On Windows, a "graceful shutdown" == shutdown(), followed by "close()". In the rest of the sockets universe, you'd instead just use "close()", perhaps in conunction with setsockopt(SO_LINGER) and/or shutdown: beej.us/guide/bgnet/output/html/multipage/… Commented Aug 12, 2015 at 21:42
  • @paulsm4 acutally, shutdown is always required to discover errors. Shutdown makes sure everything was sent successfully. Close has no error reporting. Commented Aug 12, 2015 at 21:46

1 Answer 1

2

A graceful shutdown is done by first shutting down your outgoing channel socket.Shutdown(SocketShutdown.Send)), and keep reading on the socket.

The other side will read your shutdown request as a 0-byte message, and after sending all remaining data it should respond by closing its socket. This causes your side to receive a 0 byte message, ending the transaction.

Sign up to request clarification or add additional context in comments.

8 Comments

@usr with typical request-response protocols this is true, but in a full-duplex scenario you might not know when you're done.
ALSO: It's important to note that shutdown() doesn't actually close the file descriptor—it just changes its usability. To free a socket descriptor, you need to use close().
@usr - If I'm done reading and writing after calling Shutdown, what should my server do with the TcpClient? If I call Client.Close, that is causing a hard reset, which I want to avoid. But, I also don't want to read or write anymore because I'm purposely closing the connection because bad data was sent and I don't want to read any further. Are you saying I have to keep reading if I want to finish the graceful shutdown?
@Chad Close after shutdown does nothing on the network that I'm aware of. Both parties have already agreed to end communicating. Close only releases kernel resource and it should/must be called. There is no point in reading after shutdown, always reads zero immediately.
You must call close(). You may call shutdown(), although it's not often needed. Especially on non-windows platforms.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.