#include "Flatline.h" thread int UDPServer_Socket = 0; bool NetUDPServer_Listen(uint16_t port, bool (*packet_callback)(char* data, int datalen, int from)) { UDPServer_Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (UDPServer_Socket < 0) { DDrStartupMessage("could not create socket"); return false; } sockaddr_in address; memset(&address, 0, sizeof(sockaddr_in)); address.sin_family = AF_INET; address.sin_addr.s_addr = htonl(INADDR_ANY); address.sin_port = htons(port); if (bind(UDPServer_Socket, (sockaddr*)&address, sizeof(sockaddr_in)) < 0) { DDrStartupMessage("could not bind port %d", port); closesocket(UDPServer_Socket); return false; } char data[65537]; data[sizeof(data) - 1] = '\0'; sockaddr_in from; int recvlen; for (;;) { int fromlen = sizeof(sockaddr_in); memset(&from, 0, sizeof(sockaddr_in)); recvlen = recvfrom(UDPServer_Socket, data, sizeof(data) - 1, 0, (sockaddr*)&from, (void*)&fromlen); if (!packet_callback(data, recvlen, ntohl(from.sin_addr.s_addr))) break; } closesocket(UDPServer_Socket); return true; } bool NetUDPServer_Send(sockaddr* address, char* data, int datalen) { return NetUDPSocket_Send(UDPServer_Socket, address, data, datalen); } int NetUDPSocket_Create(uint16_t port) { int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock < 0) { DDrStartupMessage("could not create socket"); return -1; } sockaddr_in address; memset(&address, 0, sizeof(sockaddr_in)); address.sin_family = AF_INET; address.sin_addr.s_addr = htonl(INADDR_ANY); address.sin_port = htons(port); if (bind(sock, (sockaddr*)&address, sizeof(sockaddr_in)) < 0) { DDrStartupMessage("could not bind port %d", port); return false; } unsigned long nonBlocking = 1; if (ioctlsocket(sock, FIONBIO, &nonBlocking)) { DDrStartupMessage("failed to set non-blocking socket"); return false; } return sock; } void NetUDPSocket_Close(int socket) { closesocket(socket); } bool NetUDPSocket_Send(int socket, const sockaddr* address, const char* data, int datalen) { int addr_size; switch (address->sa_family) { case AF_INET: addr_size = sizeof(sockaddr_in); break; case AF_INET6: addr_size = sizeof(sockaddr_in6); break; default: addr_size = sizeof(sockaddr_storage); } return sendto(socket, data, datalen, 0, address, addr_size); } bool NetUDPSocket_Recieve(int socket, sockaddr_storage* address, char* data, uint16_t* datalen) { int address_size = sizeof(sockaddr_storage); uint32_t msg_size = recvfrom(socket, data, 512, 0, (sockaddr*)address, &address_size); if (msg_size == 0) return false; else { *datalen = msg_size; return true; } }