TcpSendKeepAlive. Does it work ?

Discussion to talk about software related topics only.
Post Reply
fanat9
Posts: 56
Joined: Thu Apr 24, 2008 4:23 pm
Location: Boston
Contact:

TcpSendKeepAlive. Does it work ?

Post by fanat9 »

Trying to use new function TcpSendKeepAlive() to check tcp connection status. And it seems to be not working.
I have this function in a loop right after ReadWithTimeout() and I assume that it will detect broken tcp connection on other side. But nothing really happens.
Any body using that TcpSendKeepAlive ?
rnixon
Posts: 833
Joined: Thu Apr 24, 2008 3:59 pm

Re: TcpSendKeepAlive. Does it work ?

Post by rnixon »

Can you describe how you are testing it? What is on the other side, what you are doing to break the connection, what program is running on the other end, are you sending data or is the connection just idle, etc.
User avatar
pbreed
Posts: 1080
Joined: Thu Apr 24, 2008 3:58 pm

Re: TcpSendKeepAlive. Does it work ?

Post by pbreed »

It is "part" of a solution.

//Find out how long ago we heard from the other side of the connection.
DWORD TcpGetLastRxTime(int fd);

//If we have not heard from them in awhile then send a keepalive probe that will
//cause a response that will be seen in the last heard from above.
//This function should not be called more often then every few seconds.
void TcpSendKeepAlive (int fd);
fanat9
Posts: 56
Joined: Thu Apr 24, 2008 4:23 pm
Location: Boston
Contact:

Re: TcpSendKeepAlive. Does it work ?

Post by fanat9 »

What is on the other side, what you are doing to break the connection, what program is running on the other end, are you sending data or is the connection just idle, etc.
I have WinXP machine on other side and I'm physically unplugging cable from this PC for testing. Initially I'm was sending data both ways, but now trying with out - same problems.
Also initially I was checking for alive connection each time I was getting/sending data thru that socket. Thought it was a problem, but when I added OSTimeDly for 10 seconds got same results.

And I getting strange results from TcpGetLastRxTime right after the moment I brake the connection:
Application started
DHCP assigned IP address:192.168.10.104
TcpLastRxTime = 137.
TcpLastRxTime = 342.
TcpLastRxTime = 543.
TcpLastRxTime = 548.
TcpLastRxTime = 548.
TcpLastRxTime = 548.
TcpLastRxTime = 548.
TcpLastRxTime = 548.
TcpLastRxTime = 548.
TcpLastRxTime = 548.

It doesn't look right. Isn't it ?
Siavash
Posts: 2
Joined: Tue Jul 07, 2009 12:56 pm

Re: TcpSendKeepAlive. Does it work ?

Post by Siavash »

the number returned by TcpGetLastRxTime() is the number of system time ticks elapsed between system boot and the last TCP packet that was received. if you would like to display this number in seconds since start up, all you have to do is divide the returned value by the constant "TICKS_PER_SECOND", which is 20 by default. in other words when you get TcpLastRxTime = 200, that means 10 seconds have elapsed since system start up and the last received TCP packet.

the way you check for a dead connection is: you store the value of TcpGetLastRxTime() in a variable, then u send a keep alive packet with TcpSendKeepAlive(int fd); If the connection is still alive, this will cause the other end to send us a dummy packet, which in turn will update LastRxTime (since a new packet has been received). now if you call TcpGetLastRxTime() again, the value returned should be different than the old value which you stored in a variable. If the connection is dead, the value returned will remain the same since no new packets are being received.

so in the returned values you posted, its obvious that the connection was lost some where after 548 time ticks. your code should have an if statement that detect the repeated LastRxTime and closes the connection. heres an example:


DWORD last_rx_time = TcpGetLastRxTime(fdnet);
TcpSendKeepAlive(fdnet);
OSTimeDly(10 * TICKS_PER_SECOND); // allow time for other end to respond to keepalive

if (last_rx_time == TcpGetLastRxTime(fdnet))
{
iprintf("Connection timed out, closing socket\n");
close(fdnet);
fdnet = 0;
}
fanat9
Posts: 56
Joined: Thu Apr 24, 2008 4:23 pm
Location: Boston
Contact:

Re: TcpSendKeepAlive. Does it work ?

Post by fanat9 »

Thank you Siavash.

But, I have to admit what such using of this functions wasn't clear from documentation. I assumed that, if keep-alive didn't get response from remote system, next time I will try to use socket it will return error code - probably related to MAX_TCP_RETRY limit or READ/WRITE_TIMEOUTs. That was, clearly, wrong assumption.

The only questions I still have is why this functions should not be used "more often then every few seconds" ?
What exactly may/will go wrong if let say you forced to check connection more often? In other words, what is the situations I have to prevent at any cost ?

From my perspective sending simplest data packet for check or sending ACK packet - same thing. But keep-alive looks more convenient and it will work independent from version of protocol system use.
Siavash
Posts: 2
Joined: Tue Jul 07, 2009 12:56 pm

Re: TcpSendKeepAlive. Does it work ?

Post by Siavash »

well the main reason is, if you send keepalive packets too often, your increasing network traffic and there is no real benefit from sending it more often. Unless of course you have a situation where its absolutely necessary to close the connection the instance they are dead. So basically you have to balance increased network traffic vs. hogged sockets by dead connections and find the sweet spot that maximizes performance for you particular situation... but as a rule of thumb, its a really rare that you can benefit from sending them more often than once every few seconds.

as far as the GetLastRxTime function goes, you want to allow time for the keep alive packet to get to the client and for him to send the ack back, other wise if you check the last RX time too fast, you might check it before the ack packet had a chance to arrive and your code will mistakenly assume that the connection is dead and close the socket.
fanat9
Posts: 56
Joined: Thu Apr 24, 2008 4:23 pm
Location: Boston
Contact:

Re: TcpSendKeepAlive. Does it work ?

Post by fanat9 »

Ok. And thank you again.
Post Reply