#include "networking.h" char buffer[1000]; //////////// // Server // //////////// server_connection::server_connection() { struct ifaddrs *ifAddrStruct = NULL; struct ifaddrs *ifa = NULL; void *tmpAddrPtr = NULL; char addressBuffer[INET_ADDRSTRLEN]; // Creating socket file descriptor if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // Get available interfaces getifaddrs(&ifAddrStruct); // Display them and have the user select which to use clear(); int i = 0; mvprintw(0, 0, "Select interface to listen"); for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) { if (!ifa->ifa_addr) { continue; } if (ifa->ifa_addr->sa_family == AF_INET) { tmpAddrPtr = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN); i++; mvprintw(i, 0, "%d) %s", i, addressBuffer); } } int key = getch(); while ((key - '1') < 0 || (key - '1') > i - 1) key = getch(); i = 0; key = key - '1'; // Use the selected IP to bind to the port address.sin_family = AF_INET; address.sin_port = htons(BATTLESHIP_PORT); for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) { if (!ifa->ifa_addr) { continue; } if (ifa->ifa_addr->sa_family == AF_INET) { tmpAddrPtr = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN); if (i == key) { address.sin_addr.s_addr = inet_addr(addressBuffer); break; } i++; } } // Free the addresses, we don't need them anymore if (ifAddrStruct != NULL) freeifaddrs(ifAddrStruct); // Bind the socket if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } if (listen(server_fd, 0) < 0) { perror("listen failed"); exit(EXIT_FAILURE); } clear(); mvprintw(0, 0, "Waiting for connections"); mvprintw(1, 0, "IP: %s", addressBuffer); refresh(); if ((server_sock = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { perror("accept failed"); exit(EXIT_FAILURE); } } server_connection::~server_connection() { close(server_sock); close(server_fd); } std::string server_connection::exchange_message(const std::string &message) { strcpy(buffer, message.c_str()); buffer[message.length()] = ';'; int bytes_to_send = message.length() + 1; send(server_sock, buffer, bytes_to_send, 0); char tmp = 0; std::string received; while (true) { read(server_sock, &tmp, 1); if (tmp == ';') break; received.push_back(tmp); } return received; } //////////// // Client // //////////// client_connection::client_connection() { // Create socket if ((client_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket failed"); exit(EXIT_FAILURE); } memset(&serv_addr, '0', sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(BATTLESHIP_PORT); clear(); while (true) { mvprintw(0, 0, "Enter IP address:"); move(1, 0); clrtoeol(); refresh(); std::string ip = getstring(); if (inet_pton(AF_INET, ip.c_str(), &serv_addr.sin_addr) <= 0) { mvprintw(3, 0, "Invalid IP"); refresh(); continue; } if (connect(client_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { move(3, 0); clrtoeol(); mvprintw(3, 0, "Failed to connect"); continue; } break; } } client_connection::~client_connection() { close(client_sock); } std::string client_connection::exchange_message(const std::string &message) { char tmp = 0; std::string received; while (true) { read(client_sock, &tmp, 1); if (tmp == ';') break; received.push_back(tmp); } strcpy(buffer, message.c_str()); buffer[message.length()] = ';'; int bytes_to_send = message.length() + 1; send(client_sock, buffer, bytes_to_send, 0); return received; }