2

I'm pretty new to socket programming. Our application uses sockets to communicate with a device our company manufactures. We have a problem with the socket sometimes taking a long time to close.

Here's the code that is run when it is time to close the socket:

if (client != null) {
    try {
        if (client.Connected) {
            client.Disconnect(false);
            client.Shutdown(SocketShutdown.Both);
        }

        client.Close();
    } catch (SocketException) {
    }

    client = null;
}

I've read the documentation for the Socket.Shutdown method and the responses to this question and I'm confused. Will any data that is pending transfer from the remote system to this system, or vice versa, be transferred or abandoned? If the data that is pending transfer is abandoned, what could be delaying the socket's closure?

Community
  • 1
  • 1
Tony Vitabile
  • 8,298
  • 15
  • 67
  • 123
  • 1
    There is already a good explanation of this here: https://stackoverflow.com/questions/4160347/close-vs-shutdown-socket - I would jsut close the socket and dispose it - btw: client.Connected is not reliable – Random Dev Jul 01 '14 at 18:42
  • @CarstenKönig: if `client.Connected` is not reliable, is there a reliable alternative? – Tony Vitabile Jul 01 '14 at 19:00
  • You can call `Close()` regardless of whether the socket thinks its connected to something. – C.Evenhuis Jul 01 '14 at 19:01
  • @TonyVitabile I cannot find it right now (should be here somewhere) but Connect is the state at the last I/O - so I think the trick was to try to write or read a 0 byte block or something – Random Dev Jul 01 '14 at 19:35

1 Answers1

2

Call Shutdown before close so that you can make sure that all data queued is actually received.

Do not call Disconnect. Why would this be necessary? No reason. This is especially wrong before shutting down. Think whether this makes sense or not.

Call Dispose or Close after Shutdown to release all OS resources. The connection is reliably closed by now.

Do not swallow SocketException. Why are you doing this? You'll never find out that data you sent was not received.

We have a problem with the socket sometimes taking a long time to close.

How do you know? What are the symptoms of this?

usr
  • 168,620
  • 35
  • 240
  • 369
  • The code in question runs in a proprietary architecture as a thing called a `Module`. `Modules` have several well defined states, including `Initializing`, `Running`, `Stopping`, and `Stopped`. This particular `Module` is a driver for a proprietary device that our company makes.Sometimes, when this particular `Module` is told to stop, it can take a couple of minutes for the stop to finish. I know this because I added trace points that indicate when the `client.Close()` is called. It doesn't happen every time. I have to figure out why it happens when it does happen. – Tony Vitabile Jul 02 '14 at 02:20
  • This is probably not due to some mistake on your part. If you use the proper shutdown/close sequence you've done everything right. Consider just letting the shutdown run in the background and proceeding with the rest of your code (concurrently) so that the long shutdown does not cause delays. – usr Jul 02 '14 at 09:08
  • Sadly, letting the shutdown run in the background is not possible in this case. This issue is occurring in response to configuration changes the user is making in the driver. The device gets confused if there are 2 drivers talking to it at the same time and sends its response to the wrong one. In this case, the current connection has to terminate before the next one starts to avoid other problems. – Tony Vitabile Jul 02 '14 at 12:45
  • Further, another developer wrote this code, someone is much more familiar with socket programming than I am. I've inherited it, so I have no idea what could be wrong. – Tony Vitabile Jul 02 '14 at 12:46
  • I understand. Is your question answered? If the remote side does not quickly shut down there's nothing you can do. You can close with lingering enabled to get an instant close but the connection will still be active and the device will still be "confused". – usr Jul 02 '14 at 12:47
  • It turns out that there was nothing at all wrong with the code, except for the fact that `Shutdown` was called before `Close`. The issue was in a totally unrelated part of the code. – Tony Vitabile Jul 18 '14 at 13:14
  • Shutdown is supposed to be called before close and it is important that you call it. – usr Jul 18 '14 at 13:50
  • Sorry, I meant to say that `Shutdown` was called AFTER `Close`, not before. – Tony Vitabile Jul 18 '14 at 13:51