Friday, March 2, 2018

C++ Sockets Example

I hadn't done network programming in C++ in quite some time, so I did a search for some material to refresh my memory. It took longer than I thought it would to find a simple, working example, so I will post the one I eventually found here for future reference. Here is the post from StackOverflow that I found helpful: link.

To send a UDP message to the socket, run this from the command line:

  • echo -n "my message" > /dev/udp/127.0.0.1/50037

Here is the code. To make the recvfrom() call blocking, change the MSG_DONTWAIT parameter to 0, and remove the check for the -1 return value, which is what the non-blocking recvfrom() returns when it doesn't receive anything.

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>

int main( void )
{
    int fd;
    if ( (fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
        perror( "socket failed" );
        return 1;
    }

    struct sockaddr_in serveraddr;
    memset( &serveraddr, 0, sizeof(serveraddr) );
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons( 50037 );
    serveraddr.sin_addr.s_addr = htonl( INADDR_ANY );

    if ( bind(fd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0 ) {
        perror( "bind failed" );
        return 1;
    }

    char buffer[200];
    //for ( int i = 0; i < 4; i++ ) {
    while( 1 ) {
        int length = recvfrom( fd, buffer, sizeof(buffer) - 1, MSG_DONTWAIT, NULL, 0 );
        if( length == -1 ) {
            sleep(1);
        }
        else if ( length < 0 ) {
            perror( "recvfrom failed" );
            break;
        } else {
            buffer[length] = '\0';
            printf( "%d bytes: '%s'\n", length, buffer );
        }
    }

    close( fd );
}