#include #include #include #include #include #include #include #include #include "net.h" /** * Server side function; start server on specified port * @param[in] port Port on which server should listen * @return Listening socket */ int server_start(const char* port) { int status; int serversock; struct addrinfo hints, *result, *tmp; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; // IPv4 or IPv6 hints.ai_socktype = SOCK_STREAM; // TCP socket hints.ai_flags = AI_PASSIVE; // wildcard IP hints.ai_protocol = 0; // any protocol status = getaddrinfo(NULL, port, &hints, &result); if(status != 0) { printf("getaddrinfo: %s\n", gai_strerror(status)); exit(EXIT_FAILURE); } // iterate over linked addrinfo list and use first useable entry for(tmp = result; tmp != NULL; tmp = tmp->ai_next) { int yes=1; // create socket serversock = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol); if(serversock == -1) continue; // try to reuse still open sockets in TIME_WAIT state setsockopt(serversock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); // try to bind to address/port if(bind(serversock, tmp->ai_addr, tmp->ai_addrlen) == 0) break; // Success! close(serversock); } if(tmp == NULL) { printf("failed to bind\n"); exit(EXIT_FAILURE); } freeaddrinfo(result); // start listening status = listen(serversock, 1); if(status == -1) { printf("listen: %s\n", strerror(status)); exit(EXIT_FAILURE); } return serversock; } /** * Server side function; accepts connections from clients * @param[in] serversock Socket on which server is listening * @param[in] count Number of clients that should connect * @return List of $count open sockets with connections to clients */ int* server_get_players(int serversock, const uint8_t count) { int* clientsocks; int i; assert(count < MAX_PLAYERS && count > 0); clientsocks = malloc(count*sizeof(int)); if(clientsocks == NULL) { printf("server_get_players: Out of memory\n"); exit(EXIT_FAILURE); } // accept connections for(i=0; iai_next) { // create socket sock = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol); if(sock == -1) continue; // connect! if(connect(sock, tmp->ai_addr, tmp->ai_addrlen) != -1) break; // Success! close(sock); } if(tmp == NULL) { printf("failed to connect\n"); exit(EXIT_FAILURE); } freeaddrinfo(result); return sock; } void server_start_game(int* clients, const uint8_t clientcount, const char* usernames[]) { uint8_t* buf; uint8_t usercount = clientcount + 1; // 1 more user (server) than clients uint32_t pos = 0; uint32_t buflen = 2 + usercount; // type + usercount + (usercount * len) for(int i=0; i