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

TCPEchoHandler.cpp

Committer:
darran
Date:
2010-06-12
Revision:
0:c4e397ba6a9d

File content as of revision 0:c4e397ba6a9d:

#include "TCPEchoHandler.h"

// When the constructor's called, initialise the member variables
TCPEchoHandler::TCPEchoHandler(TCPSocket* tcpClientSocket)
        : NetService()
        , clientSocket(tcpClientSocket)
        , closed(0)
        , timeoutWatchdog() {
    // Wire up the event handler on the client TCP socket
    clientSocket->setOnEvent(this, &TCPEchoHandler::onTCPSocketEvent);
}

TCPEchoHandler::~TCPEchoHandler() {
    // Close the socket on destruction
    close();
}

void TCPEchoHandler::onTCPSocketEvent(TCPSocketEvent e) {
    switch (e) {
        // If the socket is readable, do stuff
        case TCPSOCKET_READABLE:
            // Disable the timeout watchdog timer
            timeoutWatchdog.detach();
            // Read in any available data into the buffer
            char buff[128];
            while ( int len = clientSocket->recv(buff, 128) ) {
                // And send straight back out again
                clientSocket->send(buff, len);
            }
            // Reset timeout countdown
            setTimeout(ECHO_TIMEOUT);
            break;
        case TCPSOCKET_CONTIMEOUT:
        case TCPSOCKET_CONRST:
        case TCPSOCKET_CONABRT:
        case TCPSOCKET_ERROR:
        case TCPSOCKET_DISCONNECTED:
            // Close the socket on any terminal TCP event
            close();
            break;
    }

}

void TCPEchoHandler::close() {
    // Prevent recursive calling or calling on an object being destructed by someone else
    if ( closed )
        return;
    closed = 1;
    timeoutWatchdog.detach();
    if ( clientSocket ) {
        clientSocket->resetOnEvent();
        clientSocket->close();
        delete clientSocket; //This fn might have been called by this socket (through an event), so DO NOT DESTROY IT HERE
    }
    // Flags this service as closed - will be destructed and deleted on
    // the next call of NetService::poll() by Net::poll()
    NetService::close();
}

void TCPEchoHandler::setTimeout(unsigned int timeout) {
    // Attach our timeout handler to the timeout watchdog timer to close the socket if no activity
    timeoutWatchdog.attach_us<TCPEchoHandler>(this, &TCPEchoHandler::onTimeout, ECHO_TIMEOUT * 1000);
}

void TCPEchoHandler::onTimeout() {
    // Nothing fancy, just close the socket and mark this class for destruction
    close();
}