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!