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.
EchoServer.cpp@0:c4e397ba6a9d, 2010-06-12 (annotated)
- Committer:
- darran
- Date:
- Sat Jun 12 19:05:52 2010 +0000
- Revision:
- 0:c4e397ba6a9d
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
darran | 0:c4e397ba6a9d | 1 | #include "EchoServer.h" |
darran | 0:c4e397ba6a9d | 2 | |
darran | 0:c4e397ba6a9d | 3 | EchoServer::EchoServer() { |
darran | 0:c4e397ba6a9d | 4 | // Create the sockets and set the callbacks |
darran | 0:c4e397ba6a9d | 5 | tcpSock = new TCPSocket; |
darran | 0:c4e397ba6a9d | 6 | tcpSock->setOnEvent(this, &EchoServer::onNetTcpSocketEvent); |
darran | 0:c4e397ba6a9d | 7 | udpSock = new UDPSocket; |
darran | 0:c4e397ba6a9d | 8 | udpSock->setOnEvent(this, &EchoServer::onNetUdpSocketEvent); |
darran | 0:c4e397ba6a9d | 9 | } |
darran | 0:c4e397ba6a9d | 10 | |
darran | 0:c4e397ba6a9d | 11 | EchoServer::~EchoServer() { |
darran | 0:c4e397ba6a9d | 12 | // Delete the sockets on destruction |
darran | 0:c4e397ba6a9d | 13 | delete tcpSock; |
darran | 0:c4e397ba6a9d | 14 | delete udpSock; |
darran | 0:c4e397ba6a9d | 15 | } |
darran | 0:c4e397ba6a9d | 16 | |
darran | 0:c4e397ba6a9d | 17 | void EchoServer::bind(int tcpPort, int udpPort) { |
darran | 0:c4e397ba6a9d | 18 | // bind and listen on TCP |
darran | 0:c4e397ba6a9d | 19 | tcpSock->bind(Host(IP_ADDR_ANY, tcpPort)); |
darran | 0:c4e397ba6a9d | 20 | tcpSock->listen(); |
darran | 0:c4e397ba6a9d | 21 | // bind UDP |
darran | 0:c4e397ba6a9d | 22 | udpSock->bind(Host(IP_ADDR_ANY, udpPort)); |
darran | 0:c4e397ba6a9d | 23 | } |
darran | 0:c4e397ba6a9d | 24 | |
darran | 0:c4e397ba6a9d | 25 | void EchoServer::onNetTcpSocketEvent(TCPSocketEvent e) { |
darran | 0:c4e397ba6a9d | 26 | // We're only interested in the ACCEPT event where we need to accept |
darran | 0:c4e397ba6a9d | 27 | // the incoming connection |
darran | 0:c4e397ba6a9d | 28 | if ( e == TCPSOCKET_ACCEPT ) { |
darran | 0:c4e397ba6a9d | 29 | TCPSocket* tcpClientSocket; |
darran | 0:c4e397ba6a9d | 30 | Host client; |
darran | 0:c4e397ba6a9d | 31 | if ( tcpSock->accept(&client, &tcpClientSocket) ) { |
darran | 0:c4e397ba6a9d | 32 | printf("onNetTcpSocketEvent : Could not accept connection.\r\n"); |
darran | 0:c4e397ba6a9d | 33 | return; //Error in accept, discard connection |
darran | 0:c4e397ba6a9d | 34 | } |
darran | 0:c4e397ba6a9d | 35 | // We can find out from where the connection is coming by looking at the |
darran | 0:c4e397ba6a9d | 36 | // Host parameter of the accept() method |
darran | 0:c4e397ba6a9d | 37 | IpAddr clientIp = client.getIp(); |
darran | 0:c4e397ba6a9d | 38 | printf("Incoming TCP connection from %d.%d.%d.%d\r\n", clientIp[0], clientIp[1], clientIp[2], clientIp[3]); |
darran | 0:c4e397ba6a9d | 39 | // Create TCPEchoHandler and pass client socket |
darran | 0:c4e397ba6a9d | 40 | TCPEchoHandler* tcpHandler = new TCPEchoHandler(tcpClientSocket); //TCPSocket ownership is passed to handler |
darran | 0:c4e397ba6a9d | 41 | // The handler object will destroy itself when done, or will be destroyed on Server destruction |
darran | 0:c4e397ba6a9d | 42 | } |
darran | 0:c4e397ba6a9d | 43 | } |
darran | 0:c4e397ba6a9d | 44 | |
darran | 0:c4e397ba6a9d | 45 | void EchoServer::onNetUdpSocketEvent(UDPSocketEvent e) { |
darran | 0:c4e397ba6a9d | 46 | // We're only interested in the READABLE event (it's the only one) |
darran | 0:c4e397ba6a9d | 47 | if ( e == UDPSOCKET_READABLE ) { |
darran | 0:c4e397ba6a9d | 48 | // No need for a handler for UDP - set up a buffer and check client |
darran | 0:c4e397ba6a9d | 49 | char buff[128]; |
darran | 0:c4e397ba6a9d | 50 | Host client; |
darran | 0:c4e397ba6a9d | 51 | IpAddr clientIp = client.getIp(); |
darran | 0:c4e397ba6a9d | 52 | printf("Incoming UDP connection from %d.%d.%d.%d\r\n", clientIp[0], clientIp[1], clientIp[2], clientIp[3]); |
darran | 0:c4e397ba6a9d | 53 | // Keep reading while there's data to be read |
darran | 0:c4e397ba6a9d | 54 | while ( int len = udpSock->recvfrom(buff, 128, &client) ) { |
darran | 0:c4e397ba6a9d | 55 | if ( len > 0 ) |
darran | 0:c4e397ba6a9d | 56 | // If there's data, send it straight back out |
darran | 0:c4e397ba6a9d | 57 | udpSock->sendto(buff, len, &client); |
darran | 0:c4e397ba6a9d | 58 | } |
darran | 0:c4e397ba6a9d | 59 | } |
darran | 0:c4e397ba6a9d | 60 | } |