Tech Off Post

Single Post Permalink

View Thread: TcpClient - Test for Disconnected?
  • User profile image

    evildictaitor said:
    The problem here is an understanding of how TCP works.

    Basically we have the concept of a packet. This goes from one computer to another. These are wrapped in a protocol called UDP, and these packets are stateless. What TCP does is put a layer on top of this, allowing you to send a "message" which is broken up by the TCP client and sent as UDP packets, before being reassembled at the other client and propagated upwards:

    message                           message out
         |                                          ^
        V                                          |
      TCP                            TCP (server)
        |                                             ^
        V                                              |
      UDP  --(udp packets)------ UDP

    TCP has the additional property that it ensures that if a packet goes missing on the underlying connection (or arrives but is "broken"), it resends it.

    The problem about "Connectedness" is that TCP is therefore not actually "connected" to anything. It "feels" like a pipe that you push things into - this goes into a series of tubes (see what I did there?) and arrives at the other side, but in reality you're actually sending little packets of information.

    So what happens when you're not sending messages? Basically in order to keep the connection "alive", and to check that the connection is "connected", the TCP layer occassionally sends dummy (non-message) UDP packets to the other side, and back again - basically an "I'm still here message".

    The big question then, is what does it "mean" to say two TCP clients are connected? Given that the Internet isn't really a series of tubes, we basically have two ways of working out whether the thing is connected:

    1) Active connection test: Send a message through the TCP client, and swallow it at the other side. If the other side sends a response (i.e. "It arrived!" packets) back, we're still connected. Most computers send back "active disconnect" packets if the other side isn't properly connected so this can be fast if the connection cannot be made, but if the connection just goes down, you actually have to wait for the packets to get there, plus a timeout time to wait to see if you ever get a "they got here" message back. This means active connection testing is upper bounded in time by the timeout length of the TCP connection, a time measured in seconds, not milliseconds.

    2) Passive connection test: This is much faster, but less reliable, and basically it says a connection is "alive" is we recieved any message within the timeout period (including ping/ack requests). Because this is passive, it can report the Connected property immediately, but because it is cached, it may be wrong.

    When Microsoft made the TcpClient / TcpListener / TcpSocket classes they decided that passive connection testing was probably the more commonly used variant of the two, and this is the reason why the Connected property is sometimes wrong.
    Actually I think your usage of "UDP" here is quite misleading as UDP is another thing that is not part of TCP/IP. I know you try to use the analogy that Unix Datagrams don't care whether the receipt receive the packets, but perheps you should just use "packets".

    And yes, the only way to ensure TCP/IP channel is "connected" is to send packet and wait for the "ACK" packet of another side.