An Echo server as described in RFC862. Written as a learning exercise for using Donatien's network stack. Hopefully of some use to others to get started with socket programming.
TCPEchoHandler.cpp
00001 #include "TCPEchoHandler.h" 00002 00003 // When the constructor's called, initialise the member variables 00004 TCPEchoHandler::TCPEchoHandler(TCPSocket* tcpClientSocket) 00005 : NetService() 00006 , clientSocket(tcpClientSocket) 00007 , closed(0) 00008 , timeoutWatchdog() { 00009 // Wire up the event handler on the client TCP socket 00010 clientSocket->setOnEvent(this, &TCPEchoHandler::onTCPSocketEvent); 00011 } 00012 00013 TCPEchoHandler::~TCPEchoHandler() { 00014 // Close the socket on destruction 00015 close(); 00016 } 00017 00018 void TCPEchoHandler::onTCPSocketEvent(TCPSocketEvent e) { 00019 switch (e) { 00020 // If the socket is readable, do stuff 00021 case TCPSOCKET_READABLE: 00022 // Disable the timeout watchdog timer 00023 timeoutWatchdog.detach(); 00024 // Read in any available data into the buffer 00025 char buff[128]; 00026 while ( int len = clientSocket->recv(buff, 128) ) { 00027 // And send straight back out again 00028 clientSocket->send(buff, len); 00029 } 00030 // Reset timeout countdown 00031 setTimeout(ECHO_TIMEOUT); 00032 break; 00033 case TCPSOCKET_CONTIMEOUT: 00034 case TCPSOCKET_CONRST: 00035 case TCPSOCKET_CONABRT: 00036 case TCPSOCKET_ERROR: 00037 case TCPSOCKET_DISCONNECTED: 00038 // Close the socket on any terminal TCP event 00039 close(); 00040 break; 00041 } 00042 00043 } 00044 00045 void TCPEchoHandler::close() { 00046 // Prevent recursive calling or calling on an object being destructed by someone else 00047 if ( closed ) 00048 return; 00049 closed = 1; 00050 timeoutWatchdog.detach(); 00051 if ( clientSocket ) { 00052 clientSocket->resetOnEvent(); 00053 clientSocket->close(); 00054 delete clientSocket; //This fn might have been called by this socket (through an event), so DO NOT DESTROY IT HERE 00055 } 00056 // Flags this service as closed - will be destructed and deleted on 00057 // the next call of NetService::poll() by Net::poll() 00058 NetService::close(); 00059 } 00060 00061 void TCPEchoHandler::setTimeout(unsigned int timeout) { 00062 // Attach our timeout handler to the timeout watchdog timer to close the socket if no activity 00063 timeoutWatchdog.attach_us<TCPEchoHandler>(this, &TCPEchoHandler::onTimeout, ECHO_TIMEOUT * 1000); 00064 } 00065 00066 void TCPEchoHandler::onTimeout() { 00067 // Nothing fancy, just close the socket and mark this class for destruction 00068 close(); 00069 }
Generated on Wed Jul 13 2022 01:13:14 by 1.7.2