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.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TCPEchoHandler.cpp Source File

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 }