From cf073d5083edaa8249ad1a960db0b2ba7619e70e Mon Sep 17 00:00:00 2001 From: Reiner Herrmann Date: Fri, 14 Jan 2011 01:56:12 +0100 Subject: added initial server/client code --- src/net.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/net.h | 10 ++++ 2 files changed, 167 insertions(+) create mode 100644 src/net.c create mode 100644 src/net.h (limited to 'src') diff --git a/src/net.c b/src/net.c new file mode 100644 index 0000000..627f2b0 --- /dev/null +++ b/src/net.c @@ -0,0 +1,157 @@ +#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)); + assert(clientsocks != NULL); + + // 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; +} + + diff --git a/src/net.h b/src/net.h new file mode 100644 index 0000000..f29100a --- /dev/null +++ b/src/net.h @@ -0,0 +1,10 @@ +#ifndef OXEN_NET_H +#define OXEN_NET_H + +#define MAX_PLAYERS 10 + +int server_start(const char* port); +int* server_get_players(int serversock, const uint8_t count); +int client_connect_server(const char* host, const char* port); + +#endif // OXEN_NET_H -- cgit v1.2.3