35

It's surprisingly hard to find a simple explanation on what these four methods actually do, aimed at network programming newbies. People usually just state what they believe is the proper way to close a socket in a particular scenario, but not what happens in the background behind each step.

Going by the teach-a-man-to-fish philosophy, can you explain the Shutdown, Disconnect, Close and Dispose methods?

relatively_random
  • 4,505
  • 1
  • 26
  • 48
  • 1
    I have found that if you are waiting for data to still go out, calling Shutdown is not enough. You may have to manually Sleep (until I find a better way) for a small period of time before calling Disconnect or Close. – Brain2000 Jul 19 '19 at 12:11
  • Did you read my answer? If I'm right there (might not be), Shutdown will not wait for data to be sent. Also, calling Close without arguments (or Dispose, which is the same thing), will abruptly stop sending data. Disconnect should block until all the remaining data is sent. Alternatively, Close with timeout will also wait until the given time, before abruptly stopping transmissions. – relatively_random Jul 19 '19 at 14:09
  • 1
    I did read your answer, but it did not work in my case. I wonder if the NIC drivers have something to do with the behavior. Even with linger set, sometimes the data does not send. I think the Windows stack has some closure bugs, with little to outdated documentation by Microsoft. – Brain2000 Jul 19 '19 at 21:27

1 Answers1

47

An answer on StackOverflow made me think I have finally reached some glimpse of an understanding. Then I went testing for a bit and here's the summary of a newbie's view. Please correct me if I'm wrong because this is based on inference, not expertise.

Shutdown

Shutdown disables the Send and/or Receive methods, depending on the provided argument. It doesn't disable the underlying protocol handling and it never blocks.

If Send is disabled, it also queues up a zero-byte send packet into the underlying send buffer. When the other side receives this packet, it knows that your socket will no longer send any data.

If Receive is disabled, any data the other side might be trying to send will be lost.

If Receive is disabled without disabling Send, it just prevents the socket from receiving data. Since no zero-byte packet will be sent, the other side won't know anything about it until it tries to send something, and only if the socket's protocol requires acknowledging.

Disconnect

First, Disconnect does the equivalent of Shutdown(SocketShutdown.Both).

Then it blocks, waiting for two things:

  1. For all the queued-up send data to be sent.
  2. For the other side to acknowledge the zero-byte packet (if applicable to the underlying protocol).

If you call Disconnect(false), system resources will be freed.

Close

Close frees system resources. May abruptly stop sending queued-up data. If called with the argument, will wait for the data to be sent, but only up to the specified timeout.

Dispose

Dispose is same as the Close overload without the timeout argument. To be more precise, Close without timeout is the same as Dispose.

If you use the using block on the socket, it will automatically call Dispose.

relatively_random
  • 4,505
  • 1
  • 26
  • 48
  • If you are going for canonical question you may want to also link to some other existing posts at the end and definitely link to MSDN documentation. Otherwise looks good. – Alexei Levenkov Feb 05 '16 at 16:59
  • Disconnect seems wrong. I doubt it waits for all data to be acknowledged. The docs say `To ensure that all data is sent and received before the socket is closed, you should call Shutdown before calling the Disconnect method.`. Also, I always thought that Shutdown waited for acknowledgement but I'm no longer 100% sure about that. The linger options seem to control what both these methods are doing so this answer might actually be right for certain linger options. – usr Feb 05 '16 at 17:15
  • @usr Good point. In that case, what does `Disconnect` actually do? An equivalent of `Close` with an ability to reuse resources? – relatively_random Feb 05 '16 at 17:23
  • I believe so but I was surprise to now read in the documentation that it *sometimes* blocks and waits for acknowledgement. – usr Feb 05 '16 at 17:52
  • 3
    @usr example on the BeginDisconnect page is completely asynchronous, and it uses Shutdown before calling BeginDisconnect. I concluded that meant Disconnect blocks. That's IMO the most frustrating thing about sockets: documentation is not exactly clear about what's happening. https://msdn.microsoft.com/en-us/library/system.net.sockets.socket.begindisconnect(v=vs.110).aspx – relatively_random Feb 05 '16 at 19:58
  • This is interesting evidence. So far I have not read any authoritative post explaining what exactly Shutdown and Disconnect do. – usr Feb 05 '16 at 23:08