1

I have a server that receives data from a client and I want to be able to determine whether the socket is still connected or not.

I am using the following function to determine the status (source):

bool SocketConnected(Socket s)
{
    bool part1 = s.Poll(1000, SelectMode.SelectRead);
    bool part2 = (s.Available == 0);
    if (part1 && part2)
        return false;
    else
        return true;
}

However, when the RTT (between Server/Client) is high (~300ms) and varies (+- 60ms), my app "crashes". From debugging I have found out that it is due to the fact that the socket is identified as not connected (SocketConnected() returns false). I know though, that the socket is still connected as I can see the client streaming the content requested from the server, and the server receiving data as captured by the Wireshark.

Should I increase the time for Poll (but I do not want to block other operations) or to use the Socket.Connected Property along with the SocketConnected()? What is the most efficient way to determine the status of the socket in volatile environments?

Sinatr
  • 20,892
  • 15
  • 90
  • 319
question_1
  • 102
  • 1
  • 10
  • It depends. You should rely on [Connected](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.socket.connected) property. Even if it's not you don't care normally. Normal error handling must take care about it. One millisecond after calling above method you may be already disconnected, what's the point to check it like this? To realize earlier? Might be important if you resources are limited. – Sinatr Nov 19 '19 at 16:44
  • @Sinatr so you are saying that I should only rely on Connected property? It would do the same job without having to poll the clients and wait for 1ms, right? Because what I did was to add another boolean var and check with the property (e.g. bool part3 = s.Connected; if (part1 && part2 && !part3)). The resources are not an issue, but if the Connected property would give the same result, then I guess there is no reason for using the Poll, right? – question_1 Nov 19 '19 at 16:57

1 Answers1

3

Unfortunately, the question and answers you've found and referenced is chock-full of terrible advice, and has nothing really constructive to say on the question. Connection-oriented protocols like TCP are specifically designed to defer errors as long as possible, to accommodate potential intermittent transport problems (network cable is unplugged, wireless connection gets reset, whatever) as much as can be done, to minimize the impact of those problems on the actual connection.

Every answer on the referenced question undermines this general strategy, or fails to address the question in a useful way, or both.

The only correct way to deal with this type of scenario is to assume that the socket is in the connection state you expect it to be (based on your own code's operation), while making sure your code has exception handling at every appropriate point of use of the socket. There is no other way.

You can look at the Connected property, but that won't tell you anything useful. The socket could transition to an unconnected state a nanosecond after you checked the property. You should also not be using "select"-based methods like Poll(), as these are inefficient and don't scale with the number of connections.

Every networked program can successfully use asynchronous I/O. If the program has a GUI (e.g. Winforms, WPF, etc.), then you can even do so while still doing all of your actual data handling in the UI thread (which gives you the luxury of not worrying so much about multithreading issues…using the modern async/await idiom would be preferable, but you can also just use the "old-school" techniques like Control.BeginInvoke() and Dispatcher.InvokeAsync()).

So, following those guidelines, the only time that the connectedness of the socket will change state in any meaningful, interesting way is when that happens intentionally, which then is detected through normal handling of graceful closure, i.e. with a read operation completing with zero bytes as the result, or when it happens due to an error, in which case your exception handling will detect the unexpectedly-disconnected state.

You cannot successfully write defect-free network I/O code without proper exception handling, so it only makes sense to rely on that exception handling for all exceptional cases.

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
  • I agree that the socket might get disconnected after checking the Connected property, but still I would rather have it as an indicator to proceed to some operations. Kudos for pointing out the inefficiency of select-based methods, which is obvious, but in most of the answers it is not mentioned (and I had doubts for getting rid of Poll()), the completeness of the answer, and the exception handling. – question_1 Nov 20 '19 at 11:47