#include #include #include #include #include #include #include #include #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[NET_MSG_OFFSET_TYPE] = msg_type_hello; buf[NET_MSG_OFFSET_PAYLOAD_LENGTH] = namelen+2; memcpy(buf+NET_MSG_OFFSET_PAYLOAD, 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 player_list* client_recv_player_list(int sock, uint8_t data_len) { uint8_t buf[data_len]; player_list* players; uint32_t pos; recv(sock, buf, data_len, 0); assert(buf[NET_MSG_OFFSET_TYPE] == msg_type_start_game); players = malloc(sizeof(player_list)); if(players == NULL) { printf("client_recv_player_list: Out of memory\n"); exit(EXIT_FAILURE); } pos = NET_MSG_OFFSET_PAYLOAD; players->count = buf[pos++]; // read usernames from buffer for(int i=0; icount; 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; } static hand* client_recv_deal_cards(int sock, uint8_t data_len) { uint8_t buf[data_len]; hand* h = malloc(sizeof(hand)); assert(data_len == 2+MAX_HAND_CARDS); // deal_cards packet have fixed size recv(sock, buf, data_len, 0); assert(buf[NET_MSG_OFFSET_TYPE] == msg_type_deal_cards); for(int i=0; i