From 3ad3d73a2fe832c8bc9ad11cbf841be833d97438 Mon Sep 17 00:00:00 2001 From: beta Date: Sat, 27 Apr 2019 16:05:49 -0500 Subject: [PATCH] networking stuff --- .vscode/settings.json | 40 +++++++++- includes/client.hpp | 63 ++++++++++++++++ includes/common.hpp | 23 ++++++ includes/game.hpp | 10 +-- includes/server.hpp | 38 ++++++++++ install.sh | 0 makefile | 19 +++-- source/client.cpp | 159 +++++++++++++++++++++++++++++++++++++++ source/client_driver.cpp | 15 ++++ source/game.cpp | 1 + source/server.cpp | 115 ++++++++++++++++++++++++++++ source/server_driver.cpp | 8 ++ thanks.md | 1 + 13 files changed, 478 insertions(+), 14 deletions(-) create mode 100644 includes/client.hpp create mode 100644 includes/common.hpp create mode 100644 includes/server.hpp create mode 100644 install.sh create mode 100644 source/client.cpp create mode 100644 source/client_driver.cpp create mode 100644 source/server.cpp create mode 100644 source/server_driver.cpp create mode 100644 thanks.md diff --git a/.vscode/settings.json b/.vscode/settings.json index 62e0df7..ad60a18 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,6 +3,44 @@ "*.cl": "c", "*.tpl": "html", "*.cool": "java", - "cmath": "cpp" + "cmath": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "array": "cpp", + "*.tcc": "cpp", + "chrono": "cpp", + "cstdint": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "fstream": "cpp", + "functional": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "memory": "cpp", + "ostream": "cpp", + "ratio": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "system_error": "cpp", + "thread": "cpp", + "cinttypes": "cpp", + "type_traits": "cpp", + "tuple": "cpp", + "typeinfo": "cpp", + "utility": "cpp", + "cstring": "cpp", + "algorithm": "cpp" } } \ No newline at end of file diff --git a/includes/client.hpp b/includes/client.hpp new file mode 100644 index 0000000..d0d38c9 --- /dev/null +++ b/includes/client.hpp @@ -0,0 +1,63 @@ +#ifndef __BETACORE_CLIENT_HPP__ +#define __BETACORE_CLIENT_HPP__ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include "common.hpp" + +namespace betacore{ + + +class Client{ + private: + bool _online = false; + bool _running= false; + char key = 'Z'; + int _port; + std::string _address; + MODE _mode; + int _client_socket; + std::function _update; + struct sockaddr_in _server_address; + struct hostent * _server; + + + std::string encode(const SHAPE &shape); + std::string crypt(const std::string &shape); + + + std::string raw(const SHAPE &shape); + SHAPE parse(const std::string &message); + + SHAPE decode(const std::string &message); + /** + * Function for Thread for getting information from server + */ + void listener(); + /** + * Function for Thread for sending to server + */ + void sender(); + void start(); + void stop(); + public: + Client(MODE mode, int port, std::string address, std::function &update); + void kill(); + bool running(); + void send(bool encrypt, SHAPE shape); + + +}; +} +#endif \ No newline at end of file diff --git a/includes/common.hpp b/includes/common.hpp new file mode 100644 index 0000000..de71aa1 --- /dev/null +++ b/includes/common.hpp @@ -0,0 +1,23 @@ +#ifndef __BETACORE_COMMON_HPP__ +#define __BETACORE_COMMON_HPP__ + +#define BUFFER_SIZE 1024 +namespace betacore +{ +enum SHAPE{ + NONE, + TRIANGLE, + CIRCLE, + SQUARE, + PENTAGON, + UNKOWN +}; +enum MODE +{ + ALICE, + BOB, + EVE +}; + +} +#endif \ No newline at end of file diff --git a/includes/game.hpp b/includes/game.hpp index f679910..d0ebaa1 100644 --- a/includes/game.hpp +++ b/includes/game.hpp @@ -17,16 +17,10 @@ #include #include #define PI 3.14159265359 +#include "../includes/common.hpp" namespace betacore { -enum SHAPE{ - NONE, - TRIANGLE, - CIRCLE, - SQUARE, - PENTAGON, - UNKOWN -}; + class Game { private: diff --git a/includes/server.hpp b/includes/server.hpp new file mode 100644 index 0000000..c020745 --- /dev/null +++ b/includes/server.hpp @@ -0,0 +1,38 @@ +#ifndef __BETACORE_SERVER_HPP__ +#define __BETACORE_SERVER_HPP__ +#include + + +#include +#include +#include +#include +#include +#include +namespace betacore +{ + + +class Server +{ +private: + bool online = false; + bool server_running= false; + int port; + int server_socket; + std::vector clients; + char buffer[1024]; + struct sockaddr_in server_address; + std::vector client_socket_collection; + void start(); + void shutdown(); + void listener(); + void read_socket(int client); +public: + Server(int port); + void off(); + bool running(); +}; +} // namespace betacore + +#endif \ No newline at end of file diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..e69de29 diff --git a/makefile b/makefile index c9b577b..9279738 100644 --- a/makefile +++ b/makefile @@ -3,12 +3,21 @@ COMPILER = g++ COMPILER_FLAGS=-w SOURCE_DIR = source/ INCLUDES_DIR =-I includes/ -LINKER_FLAGS =-lSDL2 -lGL -lGLU - -all: game +LINKER_FLAGS =-lSDL2 -lGL -lGLU -lpthread +LIBRARY_FLAGS= -std=c++11 -c -fPIC -shared +SERVER_LIB=$(OUTPUT_DIR)/server.so +CLIENT_LIB=$(OUTPUT_DIR)/client.so +all: game | client_driver | server_driver game: $(SOURCE_DIR)game.cpp | make_dir - $(COMPILER) $(INCLUDES_DIR) $(SOURCE_DIR)game.cpp $(COMPILER_FLAGS) $(LINKER_FLAGS) -o $(OUTPUT_DIR)/game - + $(COMPILER) $(INCLUDES_DIR) $(SOURCE_DIR)game.cpp $(COMPILER_FLAGS) $(LINKER_FLAGS) -o $(OUTPUT_DIR)/game.out +client_lib: $(SOURCE_DIR)client.cpp | make_dir + $(COMPILER) $(LIBRARY_FLAGS) $(INCLUDES_DIR) $(SOURCE_DIR)client.cpp -lpqxx -o $(CLIENT_LIB) +client_driver: $(SOURCE_DIR)client_driver.cpp | client_lib + $(COMPILER) $(INCLUDES_DIR) $(CLIENT_LIB) $(SOURCE_DIR)client_driver.cpp $(COMPILER_FLAGS) $(LINKER_FLAGS) -o $(OUTPUT_DIR)/client.out +server_lib: $(SOURCE_DIR)server.cpp | make_dir + $(COMPILER) $(LIBRARY_FLAGS) $(INCLUDES_DIR) $(SOURCE_DIR)server.cpp -lpqxx -o $(SERVER_LIB) +server_driver: $(SOURCE_DIR)server_driver.cpp | server_lib + $(COMPILER) $(INCLUDES_DIR) $(SERVER_LIB) $(SOURCE_DIR)server_driver.cpp $(COMPILER_FLAGS) $(LINKER_FLAGS) -o $(OUTPUT_DIR)/server.out make_dir: mkdir -p $(OUTPUT_DIR) diff --git a/source/client.cpp b/source/client.cpp new file mode 100644 index 0000000..82232cd --- /dev/null +++ b/source/client.cpp @@ -0,0 +1,159 @@ +#include "../includes/client.hpp" + +namespace betacore +{ +Client::Client(MODE mode, int port, std::string address, std::function &update) : _mode(mode), + _port(port), + _address(address), + _update(update) +{ + this->start(); +} +void Client::start() +{ + std::cout + << "Start" + << "\nConnecting to: " << _address << ":" <<_port + << std::endl; + //Create a socket point + _client_socket = socket(AF_INET, SOCK_STREAM, 0); + _server = gethostbyname(_address.c_str()); + if (_client_socket < 0) + { + std::cout << "ERROR opening socket" << std::endl; + return; + } + std::cout + << "Socket Open" + << std::endl; + bzero((char *)&_server_address, sizeof(_server_address)); + _server_address.sin_family = AF_INET; + std::cout + << "AF_INT SET" + << std::endl; + bcopy((char *)_server->h_addr, (char *)&_server_address.sin_addr.s_addr, _server->h_length); + _server_address.sin_port = htons(_port); + + // Now connect to the server + if (connect(_client_socket, (struct sockaddr *)&_server_address, sizeof(_server_address)) < 0) + { + std::cout << "ERROR connecting" << std::endl; + return; + } + std::cout + << "Client Connected" + << std::endl; +} +void Client::stop() +{ + std::cout + << "Stop" + << std::endl; +} + +void Client::kill() +{ + std::cout + << "Kill" + << std::endl; + this->_online = false; +} +bool Client::running() +{ + return this->_running; +} + +SHAPE Client::parse(const std::string &message) +{ + std::stringstream stream(message); + std::string tmp; + std::vector words; + while (std::getline(stream, tmp, ':')) + words.push_back(tmp); + + if (words.size() < 2) + return NONE; + tmp = words.at(1); + SHAPE result = decode(tmp); + if (result != UNKOWN) + return result; + if (_mode == EVE) + return UNKOWN; + return decode(crypt(tmp)); +} +SHAPE Client::decode(const std::string &shape) +{ + + if (shape == "TRIANGLE") + return TRIANGLE; + if (shape == "CIRCLE") + return CIRCLE; + if (shape == "SQUARE") + return SQUARE; + if (shape == "PENTAGON") + return PENTAGON; + return UNKOWN; +} +std::string Client::crypt(const std::string &message) +{ + + std::string output = message; + for (int i = 0; i < message.size(); i++) + output[i] = message[i] ^ key; + return output; +} +std::string Client::encode(const SHAPE &shape) +{ + std::string message; + switch (shape) + { + case TRIANGLE: + message = "TRIANGLE"; + break; + case CIRCLE: + message = "CIRCLE"; + break; + case SQUARE: + message = "SQUARE"; + break; + case PENTAGON: + message = "PENTAGON"; + break; + default: + message = "UNKOWN"; + break; + } + return message; +} +void Client::send(bool encrypt, SHAPE shape) +{ + + std::string message = "SHAPE:" + encrypt ? crypt(encode(shape)) : encode(shape) + ":END"; + std::cout << "Sending Message: " << message << std::endl; + char buffer[BUFFER_SIZE]; + bzero(buffer, BUFFER_SIZE); + strcpy(buffer, message.c_str()); + if (write(_client_socket, buffer, strlen(buffer) < 0)) + { + std::cout << "Failed send to server" << std::endl; + } +} + +void Client::listener() +{ + while (_online) + { + // Now read server response + char buffer[BUFFER_SIZE]; + bzero(buffer, BUFFER_SIZE); + + if (read(_client_socket, buffer, BUFFER_SIZE-1) < 0) + { + std::cout << "ERROR reading from socket" << std::endl; + } + std::string message(buffer); + SHAPE shape = parse(buffer); + _update(shape); + } +} +} // namespace betacore \ No newline at end of file diff --git a/source/client_driver.cpp b/source/client_driver.cpp new file mode 100644 index 0000000..0da5aed --- /dev/null +++ b/source/client_driver.cpp @@ -0,0 +1,15 @@ +#include "client.hpp" +#include + +void test(betacore::SHAPE &s){ + std::cout << "It worked" << std::endl; +} +int main(int argc, char * argv[]){ + std::function fn= test; + betacore::Client client(betacore::ALICE,4444, "localhost",fn); + client.send(false, betacore::TRIANGLE); + client.send(true, betacore::TRIANGLE); + //s.off(); + //while(client.running()){} + return 0; +} diff --git a/source/game.cpp b/source/game.cpp index be442c4..7d890e0 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -668,6 +668,7 @@ void Game::on_key_right_arrow() } void Game::on_key_space() { + } void Game::on_key_enter() { diff --git a/source/server.cpp b/source/server.cpp new file mode 100644 index 0000000..9b440c1 --- /dev/null +++ b/source/server.cpp @@ -0,0 +1,115 @@ +#include "../includes/server.hpp" + +#include + +#include +#include +#include +#include + +namespace betacore +{ +Server::Server(int port) +{ + this->port = port; + std::cout << "And so it begins..." << std::endl; + this->start(); +} +void Server::start() +{ + this->server_socket = socket(AF_INET, SOCK_STREAM, 0); + if (this->server_socket < 0) + { + std::cout << "ERROR on opening socket"<< std::endl; + return; + } + std::cout << "Socket Connected"<< std::endl; + + bzero((char *)&server_address, sizeof(server_address)); + + server_address.sin_family = AF_INET; + server_address.sin_addr.s_addr = INADDR_ANY; + server_address.sin_port = htons(this->port); + + if (bind(server_socket, (struct sockaddr *)&server_address, sizeof(server_address)) < 0) + { + std::cout << "ERROR on binding "<< std::endl; + + return; + } + std::cout << "Bound"<< std::endl; + online = true; + server_running=true; + std::cout << "Server is online"<< std::endl; + std::thread listen_thread([this] { this->listener(); } ); + listen_thread.detach(); +} +void Server::listener() +{ + std::cout << "Listener "<< online << std::endl; + while (online) { + struct sockaddr_in client_address; + listen(this->server_socket, 5); + socklen_t client_socket_length = sizeof(client_address); + int client_number = + accept(server_socket, (struct sockaddr *)&client_address, &client_socket_length); + this->client_socket_collection.push_back(client_address); + this->clients.push_back(client_number); + std::cout << "New Conenction"<< std::endl; + std::thread socket_thread([this,client_number]{this->read_socket(client_number);}); + socket_thread.detach(); + } + this->shutdown(); +} +void Server::read_socket(int client) +{ + std::cout + << "Ready To Read " + << client + << std::endl; + int n; + while (online) + { + if (client < 0) + { + std::cout << "ERROR on accept"<< std::endl; + } + bzero(buffer, 256); + n = read(client, buffer, 1024); + + if (n < 0) + { + std::cout << "ERROR reading from socket"<< std::endl; + } + + printf("Here is the message: %s\n", buffer); + n = write(client, "I got your mesage\n", 18); + + if (n < 0) + { + std::cout << "ERROR Writing socket"<< std::endl; + } + } +} +void Server::shutdown() +{ + std::cout << "Server is shuting down"<< std::endl; + + for (auto socket : clients){ + std::cout + << "Closing new socket :: " + << socket + << std::endl; + close(socket); + } + std::cout << "Closing server socket" << std::endl; + close(this->server_socket); + server_running = false; +} +void Server::off(){ + this-> online = false; +} +bool Server::running(){ + return this->server_running; +} +} // namespace betacore \ No newline at end of file diff --git a/source/server_driver.cpp b/source/server_driver.cpp new file mode 100644 index 0000000..4637f31 --- /dev/null +++ b/source/server_driver.cpp @@ -0,0 +1,8 @@ +#include "server.hpp" + +int main(int argc, char * argv[]){ + betacore::Server s(4444); + //s.off(); + while(s.running()){} + return 0; +} diff --git a/thanks.md b/thanks.md new file mode 100644 index 0000000..2efb3c6 --- /dev/null +++ b/thanks.md @@ -0,0 +1 @@ +https://stackoverflow.com/questions/10673585/start-thread-with-member-function