Search code examples
c++socketstcp

Strange behaviour of TCP-connection


We have the following configuration: Server, Client, DHCP-Server. The server runs on a static IP in "client mode". This means, that server has a list of all clients (hostnames) and builds TCP-connections. Clients have dynamic IPs.

How does it working: 1) Server creates a connection to a client and 2) Server waits for any data from a client (we use ACE framework and reactor-pattern). To have the list with clients up to date, we have added an additional timer, that sends a heartbeat to all clients.

And there is one strange behavior: let's say a hostname "somehost.internal" has IP "10.10.100.50"

  1. Time = t: connect to hostname "somehost.internal"
  2. Time = t+1: change IP of the client to "10.10.100.60"
  3. Time = t+2: heartbeat timer send data to an existing endpoint (10.10.100.50) and successfully returns (why??? this IP is not accessible)
  4. in Wireshark I can see, that Retransmission packages
  5. Time = t+5: some seconds later event handler returns with an error and the connection to the endpoint (10.10.100.50) will be closed

Do you have any advice, why a blocking send-function successfully returns when remote endpoint does not exist anymore?


Solution

  • I assume in step 3 you only send a heartbeat message to the client but do not actually wait for a response from the client on that heartbeat message.

    The socket send() function only forwards the data to the OS. It does not mean that the data is actually transmitted or has been received by the peer.

    The OS buffers data, transmits data over the network, waits for acknowledgements, retransmits data, etc.. This all takes time. Eventually the OS will decide that the other end no longer responds and marks the connection as invalid.

    Only then when you perform a socket function on that connection is the application notified of any issues.