/***************************************************************************** * ___ __ __ ___ _ __ * * / _ \\ \/ // _ \ '_ \ * * | (_) |> <| __/ | | | * * \___//_/\_\\___|_| |_| * * * * The card game * * * * Copyright (C) 2011, Reiner Herrmann * * Mario Kilies * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * *****************************************************************************/ #include #include #include #include #include #include "comm.h" #include "client.h" #include "server.h" /** * Generic receive function.\n * Receives specified message type from socket. Blocks until message is fully received. * @param[in] sock Socket on which to receive * @param[in] type Message type to receive * @return Indicates success of receiving */ bool net_recv(const int sock, const msg_type_t type) { msg_t m; bool result; ssize_t len = recv(sock, &m.hdr, sizeof(msg_header_t), MSG_PEEK|MSG_WAITALL); // just peek into packet to determine message header assert(len != -1); if(m.hdr.type != type) { printf("net_recv: received message type %d instead of %d", m.hdr.type, type); return false; } m.payload = malloc(m.hdr.payload_length); // Allocate space for message payload recv(sock, &m.hdr, sizeof(msg_header_t), MSG_WAITALL); // Remove message header from socket recv(sock, m.payload, m.hdr.payload_length, MSG_WAITALL);// And then receive the payload //printf("net_recv: received msg type %d with payload length %d\n", m.hdr.type, m.hdr.payload_length); switch(type) { case msg_type_hello_c: result = server_parse_hello(&m); break; case msg_type_hello_s: result = client_parse_hello(&m); break; case msg_type_start_game: result = client_parse_player_list(&m); break; case msg_type_deal_hand: result = client_parse_deal_hand(&m); break; case msg_type_initial_stacks: result = client_parse_initial_stacks(&m); break; case msg_type_selected_card: result = server_parse_selected_card(&m); break; case msg_type_selected_card_all: result = client_parse_selected_card_all(&m); break; case msg_type_selected_stack_c: result = server_parse_selected_stack(&m); break; case msg_type_selected_stack_s: result = client_parse_selected_stack(&m); break; case msg_type_next_action: result = client_parse_next_action(&m); break; default: printf("net_recv: Unknown message type %d received!\n", type); exit(EXIT_FAILURE); break; } free(m.payload); return result; } /** * Generic send function.\n * Transmits specified message type on socket. * @param[in] sock Socket on which to send * @param[in] type Message type to send * @param[in] data Optional pointer to extra data needed by some message types * @return Indicates success of sending */ bool net_send(const int sock, const msg_type_t type, const void *data) { bool result = true; msg_t m; m.payload = malloc(NET_MSG_MAX_PAYLOAD_LENGTH); switch(type) { case msg_type_hello_c: client_prep_hello(&m); break; case msg_type_hello_s: server_prep_hello(&m, data); break; case msg_type_selected_card: client_prep_selected_card(&m); break; case msg_type_selected_stack_c: client_prep_selected_stack(&m); break; case msg_type_start_game: server_prep_start_game(&m); break; case msg_type_selected_stack_s: server_prep_selected_stack(&m); break; case msg_type_deal_hand: server_prep_deal_hand(&m, data); break; case msg_type_initial_stacks: server_prep_initial_stacks(&m); break; case msg_type_selected_card_all: server_prep_selected_card_all(&m); break; case msg_type_next_action: server_prep_next_action(&m); break; default: printf("net_send: Unknown message type %d given\n", type); exit(EXIT_FAILURE); break; } //printf("net_send: sending msg type %d with payload length %d\n", m.hdr.type, m.hdr.payload_length); send(sock, &m, sizeof(msg_header_t), 0); // Send message header first send(sock, m.payload, m.hdr.payload_length, 0); // Then send payload free(m.payload); return result; }