Hi SurferTim
Thanks for the reply.
That post concerns multiple (Telnet) clients, which can be done by creating a different Client instance for each connection. In my case, once I get this working I'll be restricting the clients to one as I would only want one connection to control the hardware at any one time (to avoid any conflicts..!). I'm only using Telnet as a test and once my skills are up to it, I intend to write a PC-based client to control the Arduino server properly. The client can include a handshaking/watchdog feature using the TCP/IP application layer, but I was hoping to use something on the transport layer.
What I'm trying to do is prove that a client is still connected and/or that the link is intact. I tacked the following code snippets to the end of w5100.cpp and EthernetServer, and amended the header files to suit.
As you're familiar with the W5100 C++ code, perhaps you could tell me where I've gone wrong
<<w5100.cpp SNIPPET BEGIN>>//Experimental DEBUG Code
uint8_t W5100Class::send_keep_alive(SOCKET s) {
// Send KEEP_ALIVE packet to socket
writeSnCR(s, Sock_SEND_KEEP);
// Wait for command to complete
do {
if ((W5100.readSnIR(s) & SnIR::TIMEOUT) == SnIR::TIMEOUT){
Serial2.print("w5100.cpp: TIMEOUT bit set\r\n"); //DEBUG CODE
W5100.writeSnIR(s, SnIR::TIMEOUT); //Write bit-clear to SnIR
return(1); //FAIL - Timeout bit set
}
}
while (readSnCR(s)); //End of command_complete loop
return(0); //Success - ACK received
} //END OF DEBUG
<<SNIPPET END>> <<EthernetServer Snippet Begin>>//Experimental DEBUG Code
size_t EthernetServer::keepalive()
{
for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
EthernetClient client(sock);
if (EthernetClass::_server_port[sock] == _port &&
client.status() == SnSR::ESTABLISHED) { //If we have a TCP connection
uint8_t ret=(W5100.send_keep_alive(sock));
return(ret);
} //End of SnSR::ESTABLISHED
return(2); //Return with no socket connected
} //End of sock loop
return(3); //Unknown error has occurred
}
//END OF DEBUG
<<SNIPPET END>> I call
server.keepalive(); from my sketch which in turn calls the w5100.send_keep_alive function - the value returned determines whether the connection is live or dead or if the client has bailed. A "Successful" return simply loops awaiting input, whilst a returned "fail" value would initiate client.stop() and make safe my I/O to avoid a runaway condition.
As you've probably guessed I'm still fairly new to programming (and TCP/IP generally) and I was expecting that when the client response to a KEEP_ALIVE failed, the SnCR register would remain high as no ACK was received. This would keep us in the command_complete do/while loop, testing for a TIMEOUT condition in the SnIR. With RTR at 200mS and RCR at 8 I was expecting to see a further 8 KEEP_ALIVE packets on the wire at 200mS intervals, followed by the SnIR/TIMEOUT bit set approximately 1800mS after the first ACK fail.
This isn't what I'm getting though and the TCP_RETRANSMIT of stale data is confusing me!
Any help would be appreciated!!
Kind Regards
Derek