0

Let's say we have a basic TCP server with a .NET TcpListener, with a basic TCP client using a .NET TcpClient.

What types of connection terminations are there, and how are they supposed to be checked for and handled?

Client

A. Client gracefully terminates the connection. The server is notified.

B. Client physically disconnects from the network. How does the server know?

C. Client program shuts down without a graceful disconnect. How does the server know?

Server

A. Server gracefully terminates the connection. The client is notified.

B. Server physically disconnects from the network. How does the client know?

C. Server program shuts down without a graceful disconnect. How does the client know?

user3822370
  • 599
  • 4
  • 16

2 Answers2

3

Cases A and C are communicated by a TCP packet with the FIN flag set in the header. It is sent by the TCP/IP stack in the OS, so it doesn't matter if the application exited abnormally. The subcase of C where the OS also failed will act like B instead.

Case B, when you've lost the ability to communicate, is more complicated. If the failure is local (e.g. disassociation from a WiFi access point), then the local end of the connection will find out immediately about a change in network status, and can infer that the connection is broken (but if not cleaned up, a connection can survive a short-term outage).

If the connections are actively transmitting data, the acknowledgements will timeout and result in retransmission attempts. A limit may be placed on retransmission attempts, resulting in an error.

If there is no traffic, then it is possible for loss of connection to go undetected for a very long time (multiple days). For this reason, TCP connections often are configured to send heartbeat packets, which must be acknowledged, and detect failure of retransmission attempts in the same manner as normal data.

Ben Voigt
  • 260,885
  • 36
  • 380
  • 671
1

The short answer is: neither knows instantly when the other disconnects. UNTIL of course something lets you know.TCP isn't a physical connection therefore it relies on signals of some sort to determine the state. Usually either by checking the connection or receiving a graceful disconnect message from the other side. There are various ways to check for connections (polling, timeouts, catching socket exceptions, etc). It really depends on framework you're using and what your needs are.

If you have the resources to poll, then you can poll ever x seconds and check the state. Etc.

Check this extension method found here.

static class SocketExtensions
{
  public static bool IsConnected(this Socket socket)
  {
    try
    {
      return !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);
    }
    catch (SocketException) { return false; }
  }
}

Basically, socket.Poll() returns true if the connection is open and there is data, or it will return true if there is no connection. socket.Available will return the number of bytes being sent. If it's 0, && .Poll() was true, then the connection is effectively closed. It gets confusing if you try to follow the true/falses, but this will return with pretty good accuracy.

Community
  • 1
  • 1
Cory
  • 1,446
  • 9
  • 19
  • When does trying to operate on a disconnected socket throw an exception? If a server operates on a disconnected socket, does it know right away? – user3822370 Oct 07 '15 at 00:58
  • If it tries to operate on a closed connection, it will most likely throw a socket exception instantly. That's not to say that EVERY socketexception is due to disconnection though. So depending on how verbose your error messages need to be, that could be a problem. See my edit. – Cory Oct 07 '15 at 01:17
  • 1
    An intentional disconnect, with the network still available, DOES let the other side know immediately. That's the `FIN` flag in the TCP header. – Ben Voigt Oct 07 '15 at 01:31
  • When connecting via a class that sends the FIN command, which I presume the .Net classes available do? I'm not an expert, by any means, but my answer is geared toward the fact that the FIN still needs to be implemented in order for the other side to receive it. So I would still consider it to be graceful. Otherwise, the heartbeat method is a good example below of how to handle it. – Cory Oct 07 '15 at 03:19
  • @Cory: `FIN`-marked packets are controlled at a lower level than any class, or even the .NET runtime itself. Those are just layers above Windows Sockets. – Ben Voigt Oct 07 '15 at 04:47
  • @BenVoigt, ah.. I was under the impression that the runtime implemented the TCP protocol. Thanks for the info. When I'm able to get some time I'll look into this further. – Cory Oct 07 '15 at 15:57