summaryrefslogtreecommitdiff
path: root/src/net.c
diff options
context:
space:
mode:
authorReiner Herrmann <reiner@reiner-h.de>2011-01-15 17:28:08 +0100
committerReiner Herrmann <reiner@reiner-h.de>2011-01-15 17:28:08 +0100
commitd9b86b44ff96e7ca87af4c5dee7a61f61b55f603 (patch)
treef23f00a10c81fc5caf0eacdf8864859db7d7d372 /src/net.c
parent490e4ac6bbcdd431fd3cbe47f276b8d4ed66dd2b (diff)
splitted net.c into server/client files
Diffstat (limited to 'src/net.c')
-rw-r--r--src/net.c332
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;
-}
-