summaryrefslogtreecommitdiff
path: root/src/net_client.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_client.c
parent490e4ac6bbcdd431fd3cbe47f276b8d4ed66dd2b (diff)
splitted net.c into server/client files
Diffstat (limited to 'src/net_client.c')
-rw-r--r--src/net_client.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/net_client.c b/src/net_client.c
new file mode 100644
index 0000000..8d07b62
--- /dev/null
+++ b/src/net_client.c
@@ -0,0 +1,140 @@
+#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"
+
+
+/**
+ * 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;
+}
+
+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;
+}
+