Labdabeta 182 Posting Pro in Training Featured Poster

Hello,

I am having a bit of an issue with my networking addition to my game engine. The engine uses SDL to provide an event-driven programming environment. I tried adding networking functionality, but it doesn't seem to work. Here is the relevant code:

//includes
#if defined(_WIN32)
    #include <winsock2.h>
    typedef int socklen_t;
#else
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <fcntl.h>
    #include <unistd.h>
#endif
typedef struct sockaddr_in sockaddr_in;
typedef struct sockaddr sockaddr;

//...

typedef struct Connection {
    int handle; // Socket handle
    void (*onReceive)(void*,unsigned int,unsigned short); // callback(data,ip,port)
    int size; //size of expected received data
};

//...

Connection *init_connection(int size, unsigned short port, void (*onReceive)(void*,unsigned int, unsigned short))
{
    unsigned long nonBlocking = 1; //windows shenanigans
    sockaddr_in address;
    Connection *ret = malloc(sizeof(Connection));
    ret->handle = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
    if (ret->handle <= 0) {
        free(ret);
        return NULL;
    }
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(port);

    if (bind(ret->handle,(const sockaddr*)&address,sizeof(sockaddr_in))<0){
        free(ret);
        return NULL;
    }

    //more windows shenanigans
#if defined(_WIN32)
    if (ioctlsocket(ret->handle,FIONBIO,&nonBlocking)) {
        free(ret);
        return NULL;
    }
#else
    if (fcntl(ret->handle,F_SETFL,O_NONBLOCK,nonBlocking) == -1) {
        free(ret);
        return NULL;
    }
#endif
    return ret;
}

//... 

void close_connection(Connection *conn)
{
    //windows ><
#if defined(_WIN32)
    closesocket(conn->handle);
#else
    close(conn->handle);
#endif
    free(conn);
}

//... 

void connection_send(Connection *conn, void *data, unsigned int ip, unsigned short port)
{
    sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = htonl(ip);
    address.sin_port = htons(port);

    sendto(conn->handle,(const char*)data,conn->size,0,(sockaddr*)&address,sizeof(sockaddr_in));
}

//... finally, inside the event loop, after processing SDL events, but before
//framerate calculations and onStep callbacks...

sockaddr_in from;
socklen_t fromlen = sizeof(from);
void *buf = malloc(conn->size);
int numReceived = recvfrom(conn->handle,(char*)buf,conn->size,0,(sockaddr*)&from,&fromlen);
if (numReceived > 0) {
    unsigned int address;
    unsigned short port;
    address = ntohl(from.sin_addr.s_addr);
    port = ntohs(from.sin_port);
    conn->onReceive(buf,address,port);
}
free(buf);

The issue is that no matter how I test the code, onReceive() is never actually called. Unfortunately, I am fairly limited in my knowledge of how to test network code. My test code is very straightforward (use port 9999 to connect to argv[1] as IP and send each keypress's key data to each other). I checked that the port in use is open on both my computers (a windows 10 desktop and a Ubuntu 15.10 laptop). I checked that all the data being passed around is valid (no returned NULL's so all the calls "succeeded"). I just can't figure out why this isn't working. I would love to be able to somehow view exactly which packets are sent and received from each port, but I do not know how to do so. Can anybody let me know how to better debug this program? Can anybody see why it isn't working?

Thanks in advance for any help!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of 1.21 million developers, IT pros, digital marketers, and technology enthusiasts learning and sharing knowledge.