diff options
| author | Reiner Herrmann <reiner@reiner-h.de> | 2011-01-15 17:28:08 +0100 |
|---|---|---|
| committer | Reiner Herrmann <reiner@reiner-h.de> | 2011-01-15 17:28:08 +0100 |
| commit | d9b86b44ff96e7ca87af4c5dee7a61f61b55f603 (patch) | |
| tree | f23f00a10c81fc5caf0eacdf8864859db7d7d372 /src/net.c | |
| parent | 490e4ac6bbcdd431fd3cbe47f276b8d4ed66dd2b (diff) | |
splitted net.c into server/client files
Diffstat (limited to 'src/net.c')
| -rw-r--r-- | src/net.c | 332 |
1 files changed, 0 insertions, 332 deletions
diff --git a/src/net.c b/src/net.c deleted file mode 100644 index ac1b652..0000000 --- a/src/net.c +++ /dev/null @@ -1,332 +0,0 @@ -#include <sys/types.h> -#include <sys/socket.h> -#include <netdb.h> -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <assert.h> -#include "net.h" -#include "player.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; i<count; i++) - { - int sock; - struct sockaddr_storage addr; - socklen_t addrlen = sizeof(addr); - sock = accept(serversock, (struct sockaddr*) &addr, &addrlen); - if(sock == -1) - { - printf("accept: %s\n", strerror(sock)); - exit(EXIT_FAILURE); - } - //printf("new client connected: %s\n", inet_ntop(sock.ss_family, get_in_addr((struct sockaddr*)&sock), INET6_ADDRSTRLEN)); - printf("new client connected (%d/%d)\n", i+1, count); - clientsocks[i] = sock; - } - - return clientsocks; -} - -/** - * Client side function; Send hello to server - * @param[in] sock Socket to use - * @param[in] username Username of player - */ -void client_hello(int sock, const char* username) -{ - uint8_t* buf; - uint8_t namelen = strlen(username); - - buf = malloc(namelen+2); // type + len + username - if(buf == NULL) - { - printf("client_hello: Out of memory\n"); - exit(EXIT_FAILURE); - } - - buf[0] = msg_type_hello; - buf[1] = namelen; - memcpy(buf+2, username, namelen); - - send(sock, buf, namelen+2, 0); - - free(buf); -} - -/** - * Client side function; connects to specified host:port - * @param[in] host Hostname of server - * @param[in] port Port of server - * @return Socket with open connection to server - */ -int client_connect_server(const char* host, const char* port) -{ - int status; - int sock; - struct addrinfo hints, *result, *tmp; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; // IPv4 or IPv6 - hints.ai_socktype = SOCK_STREAM; // TCP socket - - status = getaddrinfo(host, port, &hints, &result); - if(status != 0) - { - printf("getaddrinfo: %s\n", gai_strerror(status)); - exit(EXIT_FAILURE); - } - - // connect to first result in linked addrinfo list - for(tmp = result; tmp != NULL; tmp = tmp->ai_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 struct player_list* players) -{ - uint8_t* buf; - uint8_t usercount = players->count; - uint32_t pos = 0; - uint32_t buflen = 2 + usercount; // type + usercount + (usercount * len) - - for(int i=0; i<usercount; i++) - buflen += strlen(players->names[i]); - - buf = malloc(buflen); - if(buf == NULL) - { - printf("server_start_game: Out of memory\n"); - exit(EXIT_FAILURE); - } - buf[pos++] = msg_type_start_game; - buf[pos++] = players->count; - // copy usernames with length to buffer - for(int i=0; i<usercount; i++) - { - uint8_t len = strlen(players->names[i]); - buf[pos++] = len; - memcpy(buf+pos, players->names[i], len); - pos += len; - } - - // send to all users - for(int i=0; i<clientcount; i++) - send(clients[i], buf, buflen, 0); - - free(buf); -} - -/** - * Server side function; receive hello message from client and read username - * @param[in] sock Socket to use - * @return Username of client - */ -static char* server_recv_hello(int sock) -{ - char buf[12], *name; - uint8_t namelen; - - recv(sock, buf, 12, 0); - - assert(buf[0] == msg_type_hello); - - namelen = buf[1]; - name = malloc(namelen+1); - if(name == NULL) - { - printf("sender_recv_hello: Out of memory\n"); - exit(EXIT_FAILURE); - } - - memcpy(name, buf+2, namelen); - name[namelen] = '\0'; - - return name; -} - -/** - * Server side function; calls correct handler for incoming packet - * @param[in] sock Socket to use - * @param[in] wanted Packet type that should be handled - * @return Pointer to desired data or NULL if not in recv queue - */ -void* server_recv(int sock, uint8_t wanted) -{ - void* result = NULL; - uint8_t buf[10], type; - ssize_t len = recv(sock, buf, 10, MSG_PEEK); // just peek into packet to determine type - - assert(len != -1); - - type = buf[0]; - if(type != wanted) - return NULL; - - switch(type) - { - case msg_type_hello: - result = server_recv_hello(sock); - break; - } - - return result; -} - -static struct player_list* client_recv_player_list(int sock) -{ - uint8_t buf[200]; - struct player_list* players; - uint32_t pos; - - recv(sock, buf, 200, 0); - - assert(buf[0] == msg_type_start_game); - - players = malloc(sizeof(struct player_list)); - if(players == NULL) - { - printf("client_recv_player_list: Out of memory\n"); - exit(EXIT_FAILURE); - } - players->count = buf[1]; - - pos = 2; - // read usernames from buffer - for(int i=0; i<players->count; i++) - { - uint8_t namelen = buf[pos++]; - players->names[i] = malloc(namelen+1); - memcpy(players->names[i], buf+pos, namelen); - players->names[i][namelen] = '\0'; - pos += namelen; - } - - return players; -} - -void* client_recv(int sock, uint8_t wanted) -{ - void* result = NULL; - uint8_t buf[10], type; - ssize_t len = recv(sock, buf, 10, MSG_PEEK); // just peek into packet to determine type - - assert(len != -1); - - type = buf[0]; - if(type != wanted) - return NULL; - - switch(type) - { - case msg_type_start_game: - result = client_recv_player_list(sock); - break; - } - - return result; -} - |
