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

Revision:
0:c4e397ba6a9d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TCPEchoHandler.cpp	Sat Jun 12 19:05:52 2010 +0000
@@ -0,0 +1,69 @@
+#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();
+}