UDP Sockets

12 Jun 2010

Hi all,

I've just spent the afternoon playing around with Donatien's new network framework, specifically playing directly with the socket API.  I've got the TCP side up and running okay doing what I expected it to, but for some reason I don't seem to be able to get anything happening on UDP.

The relevant bits of the code are:

EchoServer::EchoServer() {
    UDPSocket* udpSock;
    udpSock = new UDPSocket;
    udpSock->setOnEvent(this, &EchoServer::onNetUdpSocketEvent);
}

void EchoServer::bind(int tcpPort, int udpPort) {
    udpSock->bind(Host(IP_ADDR_ANY, udpPort));
}

// This method never gets called
void EchoServer::onNetUdpSocketEvent(UDPSocketEvent e) {
    // We're only interested in the READABLE event (it's the only one)
    if ( e == UDPSOCKET_READABLE ) {
        // No need for a handler for UDP - set up a buffer and check client
        char buff[128];
        Host client;
        IpAddr clientIp = client.getIp();
        printf("Incoming UDP connection from %d.%d.%d.%d\r\n", clientIp[0], clientIp[1], clientIp[2], clientIp[3]);
        // Keep reading while there's data to be read
        while ( int len = udpSock->recvfrom(buff, 128, &client) ) {
            if ( len > 0 )
                // If there's data, send it straight back out
                udpSock->sendto(buff, len, &client);
        }
    }
}

The full program is available at http://mbed.org/users/darran/programs/EchoServer

Is there something obvious I'm doing wrong?  Admittedly it could be down to me not even sending UDP packets to the mbed correctly.  I've tried both PCATTCP (http://www.pcausa.com/Utilities/pcattcp.htm) and a small Java program I found and modified to point to my mbed's IP address (http://www.java2s.com/Tutorial/Java/0320__Network/UDPEchoClient.htm).  Neither of which appear to be eliciting any UDP events at all.

Any pointers gratefully appreciated.

13 Jun 2010

I used TCL to craft a quick script sending/receiving some data using UDP or TCP sockets.

To first verify that TCL code works, I did server and client parts and tested it on local PC. Then substituted TCL server with MBED and connecting and sending data was a breeze.

For UDP I used udp1.0.8 package from the 'net (search "TCL udp1.0.8" - first sourceforge link). TCP sockets are supported in TCL out of the box (I used ActiveTCL). If you're interested, I can post the code here.

14 Jun 2010 . Edited: 14 Jun 2010

Hi,

There was actually a bug in the UDP sockets implementation. This was oddly working fine with the NTP Client, but since the program here is acting as a server(although the client/server distinction doesn't make much sense with UDP) this bug is revealing itself...

With the new version I published today your program should be working fine, however there's a small bug in your program as well since you use the client's address before setting it at some point; it should look like:

void EchoServer::onNetUdpSocketEvent(UDPSocketEvent e) {
    // We're only interested in the READABLE event (it's the only one)
    if ( e == UDPSOCKET_READABLE ) {
        // No need for a handler for UDP - set up a buffer and check client
        char buff[128];
        Host client;
        // Keep reading while there's data to be read
        while ( int len = udpSock->recvfrom(buff, 128, &client) ) {
            if ( len > 0 )
                // If there's data, send it straight back out
                udpSock->sendto(buff, len, &client);
        }
        IpAddr clientIp = client.getIp();
        printf("Incoming UDP connection from %d.%d.%d.%d\r\n", clientIp[0], clientIp[1], clientIp[2], clientIp[3]);        
    }
}

For my tests, I've been using Python in command-line mode, the sockets API from the standard library is pretty straightforward.

Cheers,


Donatien

14 Jun 2010

Thanks very much for that, Donatien.  Glad to know I wasn't going entirely mad. :)

Without wanting to start a religious war, my test clients are in Ruby rather than Python or TCL... :)