From 3b84aa7740aab64eb0717d9b8459ec5b9e8e826a Mon Sep 17 00:00:00 2001 From: ParkSuMin Date: Wed, 30 Apr 2025 15:14:10 +0300 Subject: [PATCH 1/7] Choose hostname and port (for server and client part) --- include/client.hpp | 9 ++++----- include/server.hpp | 6 +++--- src/client/client.cpp | 28 +++++++++++++++++----------- src/client/client_main.cpp | 22 ++++++++++++++++++++-- src/server/server.cpp | 37 ++++++++++++++++--------------------- src/server/server_main.cpp | 31 ++++++++++++++++++++++++++++--- 6 files changed, 88 insertions(+), 45 deletions(-) diff --git a/include/client.hpp b/include/client.hpp index a70d040..a3e66be 100644 --- a/include/client.hpp +++ b/include/client.hpp @@ -6,16 +6,15 @@ #include #include #include - -const int PORT = 8080; - +#include class Client{ private: int sock; public: - Client() : sock(0){}; - void run(); + Client(); + void run(const std::string& h = "localhost", const unsigned short p = 1024u); int ping(struct sockaddr_in); + void game(); }; #endif \ No newline at end of file diff --git a/include/server.hpp b/include/server.hpp index af190d0..f251b08 100644 --- a/include/server.hpp +++ b/include/server.hpp @@ -7,11 +7,11 @@ #include #include #include +#include #include #include -const int PORT = 8080; -const int MAX_CLIENTS = 100; +const int MAX_CLIENTS = 512; class Server { private: @@ -20,7 +20,7 @@ private: bool check_status(Maze& maze); public: Server() : service_mode(false){}; - void start(); // Запуск сервера + void start(const std::string& h = "localhost", const unsigned short p = 1024u); // Запуск сервера }; #endif \ No newline at end of file diff --git a/src/client/client.cpp b/src/client/client.cpp index 77abbed..f668981 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -11,28 +11,33 @@ void print_instructions() { } int Client::ping(struct sockaddr_in address){ - return connect(sock, (struct sockaddr*)&address, sizeof(address)) > 0; + return connect(sock, (struct sockaddr*)&address, sizeof(address)) != 0; } -void Client::run() { - struct sockaddr_in serv_addr; - +Client::Client(){ // Создание сокета if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { throw std::runtime_error("[Client::request] connect(2) call error"); } +} + +void Client::run(const std::string& h, const unsigned short p) { + struct sockaddr_in serv_addr; serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons(PORT); - // Преобразование IP-адреса из текстового вида в бинарный - if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { - throw std::runtime_error("[Client::request] connect(2) call error"); + hostent* host_name; + host_name = gethostbyname(h.c_str()); // Преобразование названия хоста в IP-адрес. + if (host_name == nullptr) { + throw std::runtime_error("Error in gethostbyname"); } + serv_addr.sin_port = htons(p); + memcpy(&serv_addr.sin_addr.s_addr, host_name->h_addr, host_name->h_length); + // Подключение к серверу if (ping(serv_addr)) { - throw std::runtime_error("Connection lost!"); + throw std::runtime_error("Invalid hostname:port"); } std::cout << "Подключено к серверу. Введите ваше имя: "; @@ -44,8 +49,10 @@ void Client::run() { } // Отправка имени игрока на сервер send(sock, player_name.c_str(), player_name.size(), 0); - std::cout << "Игра началась!\n"; +} +void Client::game(){ + std::cout << "Игра началась!\n"; print_instructions(); char buffer[1024] = {0}; @@ -74,6 +81,5 @@ void Client::run() { break; } } - close(sock); } \ No newline at end of file diff --git a/src/client/client_main.cpp b/src/client/client_main.cpp index 15b6c27..6ecf37f 100644 --- a/src/client/client_main.cpp +++ b/src/client/client_main.cpp @@ -1,9 +1,27 @@ #include "client.hpp" -int main(){ +int main(int argc, char** argv){ + int opt; + std::string host = "localhost"; + short unsigned port = 1024u; + + while ((opt = getopt(argc, argv, "h:p:")) != -1) { + switch (opt) { + case 'h': + host = optarg; + break; + case 'p': + port = static_cast(atoi(optarg)); + break; + default: + break; + } + } + try { Client client; - client.run(); + client.run(host, port); + client.game(); } catch (const std::runtime_error& e){ std::cerr << "Client application error: " << e.what() << std::endl; return 1; diff --git a/src/server/server.cpp b/src/server/server.cpp index 668a6e3..e28427a 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -15,7 +15,7 @@ void Server::handle_client(int client_socket, bool mode) { // Получение имени игрока int bytes_received = recv(client_socket, buffer, sizeof(buffer), 0); if (bytes_received <= 0) { - std::cerr << "Ошибка получения имени игрока.\n"; + std::cout << "Ошибка получения имени игрока.\n"; close(client_socket); return; } @@ -104,42 +104,37 @@ void Server::handle_client(int client_socket, bool mode) { std::cout << "Игрок " << player_name << " отключился.\n"; } -void Server::start() { +void Server::start(const std::string& h, const unsigned short p) { int server_fd, new_socket; struct sockaddr_in address; - int opt = 1; - int addrlen = sizeof(address); if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { - perror("Ошибка создания сокета"); - exit(EXIT_FAILURE); - } - - if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { - perror("Ошибка настройки сокета"); - exit(EXIT_FAILURE); + throw std::runtime_error("Error in socket"); } address.sin_family = AF_INET; - address.sin_addr.s_addr = INADDR_ANY; - address.sin_port = htons(PORT); + hostent* host_name; + host_name = gethostbyname(h.c_str()); // Преобразование названия хоста в IP-адрес. + if (host_name == nullptr) { + throw std::runtime_error("Error in gethostbyname"); + } + address.sin_port = htons(p); + memcpy(&address.sin_addr.s_addr, host_name->h_addr, host_name->h_length); - if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) { - perror("Ошибка привязки сокета"); - exit(EXIT_FAILURE); + if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) != 0) { + throw std::runtime_error("Error in bind"); } if (listen(server_fd, MAX_CLIENTS) < 0) { - perror("Ошибка прослушивания"); - exit(EXIT_FAILURE); + throw std::runtime_error("Error in listen"); } - std::cout << "Сервер запущен на порту " << PORT << "\n"; + std::cout << "Сервер запущен на хосте " << h << " на порту " << p << std::endl; + int addrlen = sizeof(address); while (true) { if ((new_socket = accept(server_fd, (struct sockaddr*)&address, (socklen_t*)&addrlen)) < 0) { - perror("Ошибка принятия соединения"); - exit(EXIT_FAILURE); + throw std::runtime_error("Error in accept"); } std::cout << "Новое соединение установлено.\n"; diff --git a/src/server/server_main.cpp b/src/server/server_main.cpp index 15946c9..f5ffeb2 100644 --- a/src/server/server_main.cpp +++ b/src/server/server_main.cpp @@ -1,9 +1,34 @@ #include "server.hpp" int main(int argc, char **argv) { - - Server server; - server.start(); + int opt; + std::string host = "localhost"; + short unsigned port = 1024u; + while ((opt = getopt(argc, argv, "h:p:")) != -1) { + switch (opt) { + case 'h': + host = optarg; + break; + case 'p': + port = static_cast(atoi(optarg)); + break; + default: + break; + } + } + + try { + Server server; + server.start(host, port); + } catch (const std::runtime_error& e){ + std::cerr << "Client application error: " << e.what() << std::endl; + return 1; + } catch (...){ + std::cerr << "Unexpected error in client application" << std::endl; + return 2; + } + + std::cout << "Server application finished" << std::endl; return 0; } \ No newline at end of file From 79fcae617eb1624f4bc7e00bc26b8bedc6017cdb Mon Sep 17 00:00:00 2001 From: ParkSuMin Date: Wed, 30 Apr 2025 13:06:23 +0300 Subject: [PATCH 2/7] Change structure of code base --- include/maze.hpp | 4 --- include/server.hpp | 5 ++-- src/client/client.cpp | 5 ++-- src/server/server.cpp | 51 +++++++++++++++++++++----------------- src/server/server_main.cpp | 9 ++++--- 5 files changed, 40 insertions(+), 34 deletions(-) diff --git a/include/maze.hpp b/include/maze.hpp index 3c14a1d..392cf71 100644 --- a/include/maze.hpp +++ b/include/maze.hpp @@ -30,9 +30,5 @@ class Maze{ bool is_wall(int, int) const; void set_moves_left(int); - - //void generate_maze(); - //void print_maze_info(); - //void play_game(); }; #endif diff --git a/include/server.hpp b/include/server.hpp index f251b08..8e3cb16 100644 --- a/include/server.hpp +++ b/include/server.hpp @@ -16,11 +16,12 @@ const int MAX_CLIENTS = 512; class Server { private: bool service_mode; + int server_fd; void handle_client(int client_socket, bool _mode); // Принимает клиентский сокет bool check_status(Maze& maze); public: - Server() : service_mode(false){}; - void start(const std::string& h = "localhost", const unsigned short p = 1024u); // Запуск сервера + Server(const std::string& h = "localhost", const unsigned short p = 1024u, bool service_mode = false); + void start(); // Запуск сервера }; #endif \ No newline at end of file diff --git a/src/client/client.cpp b/src/client/client.cpp index f668981..6b36e82 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -31,7 +31,7 @@ void Client::run(const std::string& h, const unsigned short p) { if (host_name == nullptr) { throw std::runtime_error("Error in gethostbyname"); } - + serv_addr.sin_port = htons(p); memcpy(&serv_addr.sin_addr.s_addr, host_name->h_addr, host_name->h_length); @@ -44,9 +44,10 @@ void Client::run(const std::string& h, const unsigned short p) { std::string player_name; std::getline(std::cin, player_name); - if (ping(serv_addr)) { + if (!ping(serv_addr)) { throw std::runtime_error("Connection lost!"); } + // Отправка имени игрока на сервер send(sock, player_name.c_str(), player_name.size(), 0); } diff --git a/src/server/server.cpp b/src/server/server.cpp index e28427a..2794635 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -1,5 +1,28 @@ #include "server.hpp" +Server::Server(const std::string& h, const unsigned short p, bool service_mode){ + // Создание сокета. + server_fd = socket(AF_INET, SOCK_STREAM, 0); + if (server_fd < 0) { + throw std::runtime_error("[MultiprocessEchoServer::MultiprocessEchoServer] socket(2) call error"); + } + // Подготовка сетевого адреса для связывания. + sockaddr_in server_address; + memset(reinterpret_cast(&server_address), '\0', sizeof(server_address)); + server_address.sin_family = AF_INET; + hostent* host_name; + host_name = gethostbyname(h.c_str()); // Преобразование названия хоста в IP-адрес. + if (host_name == nullptr) { + throw std::runtime_error("[MultiprocessEchoServer::MultiprocessEchoServer] gethostbyname(3) call error"); + } + server_address.sin_port = htons(p); + memcpy(&server_address.sin_addr.s_addr, host_name->h_addr, host_name->h_length); + if (bind(server_fd, reinterpret_cast(&server_address), sizeof(server_address)) != 0) { + throw std::runtime_error("[MultiprocessEchoServer::MultiprocessEchoServer] bind(2) call error"); + } + std::cout << "Сервер запущен на хосте " << h << " на порту " << p << std::endl; +} + bool Server::check_status(Maze &maze) { return (!maze.test_mode && maze.get_moves_left() > 0); } @@ -104,36 +127,18 @@ void Server::handle_client(int client_socket, bool mode) { std::cout << "Игрок " << player_name << " отключился.\n"; } -void Server::start(const std::string& h, const unsigned short p) { - int server_fd, new_socket; - struct sockaddr_in address; - - if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { - throw std::runtime_error("Error in socket"); - } - - address.sin_family = AF_INET; - hostent* host_name; - host_name = gethostbyname(h.c_str()); // Преобразование названия хоста в IP-адрес. - if (host_name == nullptr) { - throw std::runtime_error("Error in gethostbyname"); - } - address.sin_port = htons(p); - memcpy(&address.sin_addr.s_addr, host_name->h_addr, host_name->h_length); - - if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) != 0) { - throw std::runtime_error("Error in bind"); - } +void Server::start() { + int new_socket; if (listen(server_fd, MAX_CLIENTS) < 0) { throw std::runtime_error("Error in listen"); } - std::cout << "Сервер запущен на хосте " << h << " на порту " << p << std::endl; - + sockaddr address; int addrlen = sizeof(address); + socklen_t address_size = sizeof(address); while (true) { - if ((new_socket = accept(server_fd, (struct sockaddr*)&address, (socklen_t*)&addrlen)) < 0) { + if ((new_socket = accept(server_fd, (struct sockaddr*)&address, &address_size)) < 0) { throw std::runtime_error("Error in accept"); } diff --git a/src/server/server_main.cpp b/src/server/server_main.cpp index f5ffeb2..dbeab13 100644 --- a/src/server/server_main.cpp +++ b/src/server/server_main.cpp @@ -3,9 +3,10 @@ int main(int argc, char **argv) { int opt; std::string host = "localhost"; + bool service_mode = false; short unsigned port = 1024u; - while ((opt = getopt(argc, argv, "h:p:")) != -1) { + while ((opt = getopt(argc, argv, "h:p:s:")) != -1) { switch (opt) { case 'h': host = optarg; @@ -13,14 +14,16 @@ int main(int argc, char **argv) { case 'p': port = static_cast(atoi(optarg)); break; + case 's': + service_mode = true; default: break; } } try { - Server server; - server.start(host, port); + Server server(host, port, service_mode); + server.start(); } catch (const std::runtime_error& e){ std::cerr << "Client application error: " << e.what() << std::endl; return 1; From 062f95492aa4a8d5c26ffe2720b1822e6891901f Mon Sep 17 00:00:00 2001 From: ParkSuMin Date: Wed, 30 Apr 2025 12:23:07 +0200 Subject: [PATCH 3/7] Edit throw text --- src/client/client.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/client.cpp b/src/client/client.cpp index 6b36e82..696d951 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -17,7 +17,7 @@ int Client::ping(struct sockaddr_in address){ Client::Client(){ // Создание сокета if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - throw std::runtime_error("[Client::request] connect(2) call error"); + throw std::runtime_error("Error in socket create"); } } @@ -29,7 +29,7 @@ void Client::run(const std::string& h, const unsigned short p) { hostent* host_name; host_name = gethostbyname(h.c_str()); // Преобразование названия хоста в IP-адрес. if (host_name == nullptr) { - throw std::runtime_error("Error in gethostbyname"); + throw std::runtime_error("Error in get hostname"); } serv_addr.sin_port = htons(p); From be1b36e7cebee98c5640620e3c0774298ec78771 Mon Sep 17 00:00:00 2001 From: ParkSuMin Date: Wed, 30 Apr 2025 12:24:55 +0200 Subject: [PATCH 4/7] Edit text in server cerr part --- src/server/server_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/server_main.cpp b/src/server/server_main.cpp index dbeab13..dc79331 100644 --- a/src/server/server_main.cpp +++ b/src/server/server_main.cpp @@ -25,7 +25,7 @@ int main(int argc, char **argv) { Server server(host, port, service_mode); server.start(); } catch (const std::runtime_error& e){ - std::cerr << "Client application error: " << e.what() << std::endl; + std::cerr << "Server application error: " << e.what() << std::endl; return 1; } catch (...){ std::cerr << "Unexpected error in client application" << std::endl; From 7f0e023e0c9e9a33887279876500ea488dfbd5d8 Mon Sep 17 00:00:00 2001 From: ParkSuMin Date: Wed, 30 Apr 2025 12:32:02 +0200 Subject: [PATCH 5/7] Edit throw text part in server --- src/server/server.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/server/server.cpp b/src/server/server.cpp index 2794635..1eebd45 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -4,7 +4,7 @@ Server::Server(const std::string& h, const unsigned short p, bool service_mode){ // Создание сокета. server_fd = socket(AF_INET, SOCK_STREAM, 0); if (server_fd < 0) { - throw std::runtime_error("[MultiprocessEchoServer::MultiprocessEchoServer] socket(2) call error"); + throw std::runtime_error("Error in create socket"); } // Подготовка сетевого адреса для связывания. sockaddr_in server_address; @@ -13,12 +13,12 @@ Server::Server(const std::string& h, const unsigned short p, bool service_mode){ hostent* host_name; host_name = gethostbyname(h.c_str()); // Преобразование названия хоста в IP-адрес. if (host_name == nullptr) { - throw std::runtime_error("[MultiprocessEchoServer::MultiprocessEchoServer] gethostbyname(3) call error"); + throw std::runtime_error("Error in getting hostname"); } server_address.sin_port = htons(p); memcpy(&server_address.sin_addr.s_addr, host_name->h_addr, host_name->h_length); if (bind(server_fd, reinterpret_cast(&server_address), sizeof(server_address)) != 0) { - throw std::runtime_error("[MultiprocessEchoServer::MultiprocessEchoServer] bind(2) call error"); + throw std::runtime_error("Error in bind part"); } std::cout << "Сервер запущен на хосте " << h << " на порту " << p << std::endl; } From d905c1a3f905b579465edc7341237f7654827918 Mon Sep 17 00:00:00 2001 From: ParkSuMin Date: Wed, 30 Apr 2025 19:36:14 +0300 Subject: [PATCH 6/7] Refactoring and updating Fix bug, when steps = 0, but player didn't lose --- include/client.hpp | 11 ++++--- include/maze.hpp | 30 +++++++++---------- include/server.hpp | 10 ++++--- src/client/client.cpp | 22 +++++++------- src/server/maze.cpp | 4 +-- src/server/server.cpp | 60 +++++++++++++++++++++----------------- src/server/server_main.cpp | 13 +++++++-- 7 files changed, 85 insertions(+), 65 deletions(-) diff --git a/include/client.hpp b/include/client.hpp index a3e66be..50c8cc2 100644 --- a/include/client.hpp +++ b/include/client.hpp @@ -1,5 +1,5 @@ -#ifndef CLIENT -#define CLIENT +#ifndef CLIENT_HPP +#define CLIENT_HPP #include #include @@ -7,14 +7,17 @@ #include #include #include + class Client{ private: int sock; public: Client(); - void run(const std::string& h = "localhost", const unsigned short p = 1024u); - int ping(struct sockaddr_in); + + void run(const std::string&, const unsigned short); void game(); + + int ping(struct sockaddr_in); }; #endif \ No newline at end of file diff --git a/include/maze.hpp b/include/maze.hpp index 392cf71..2c21bd9 100644 --- a/include/maze.hpp +++ b/include/maze.hpp @@ -11,24 +11,24 @@ const int MAZE_SIZE = 9; const int DIRECTIONS = 4; const int MIN_WALLS = 3; const int MAX_WALLS = 5; -const int DEFAULT_MOVES = 10; class Maze{ - private: - std::unordered_map> graph; - int moves_left; - bool is_path_exists(int, int); +private: + std::unordered_map> graph; + int moves_left; + bool is_path_exists(int start, int end); - struct Edge { - int node1, dir1; - int node2, dir2; - }; - public: - Maze(bool); - bool test_mode; - int get_moves_left() const; - bool is_wall(int, int) const; + struct Edge { + int node1, dir1; + int node2, dir2; + }; +public: + bool test_mode; - void set_moves_left(int); + Maze(bool flag, int steps); + int get_moves_left() const; + bool is_wall(int node, int direction) const; + + void set_moves_left(int _steps); }; #endif diff --git a/include/server.hpp b/include/server.hpp index 8e3cb16..cad8636 100644 --- a/include/server.hpp +++ b/include/server.hpp @@ -12,16 +12,18 @@ #include const int MAX_CLIENTS = 512; +const int BUFFER_SIZE = 1024; class Server { private: bool service_mode; - int server_fd; - void handle_client(int client_socket, bool _mode); // Принимает клиентский сокет + int server_socket; + + void handle_client(int socket, bool flag, int steps); bool check_status(Maze& maze); public: - Server(const std::string& h = "localhost", const unsigned short p = 1024u, bool service_mode = false); - void start(); // Запуск сервера + Server(const std::string& host, const unsigned short port, bool service_flag); + void start(int steps = 10); }; #endif \ No newline at end of file diff --git a/src/client/client.cpp b/src/client/client.cpp index 696d951..4ccada0 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -1,14 +1,14 @@ #include "client.hpp" -void print_instructions() { - std::cout << "Доступные команды:\n"; - std::cout << " - вперёд\n"; - std::cout << " - направо\n"; - std::cout << " - налево\n"; - std::cout << " - назад\n"; - std::cout << " - сдаюсь\n"; - std::cout << "Введите команду для хода.\n"; -} +// void print_instructions() { +// std::cout << "Доступные команды:" << std::endl; +// std::cout << " - вперёд" << std::endl; +// std::cout << " - направо" << std::endl; +// std::cout << " - налево" << std::endl; +// std::cout << " - назад" << std::endl; +// std::cout << " - сдаюсь" << std::endl; +// std::cout << "Введите команду для хода" << std::endl; +// } int Client::ping(struct sockaddr_in address){ return connect(sock, (struct sockaddr*)&address, sizeof(address)) != 0; @@ -53,8 +53,8 @@ void Client::run(const std::string& h, const unsigned short p) { } void Client::game(){ - std::cout << "Игра началась!\n"; - print_instructions(); + std::cout << "Игра началась!" << std::endl; + //print_instructions(); char buffer[1024] = {0}; while (true) { diff --git a/src/server/maze.cpp b/src/server/maze.cpp index 7225f6c..1ac2db1 100644 --- a/src/server/maze.cpp +++ b/src/server/maze.cpp @@ -1,14 +1,14 @@ #include "maze.hpp" #include -Maze::Maze(bool _test_mode){ +Maze::Maze(bool _test_mode, int _steps){ std::vector edges = { {0, 1, 1, 3}, {0, 0, 3, 2}, {1, 1, 2, 3}, {1, 0, 4, 2}, {2, 0, 5, 2}, {3, 1, 4, 3}, {3, 0, 6, 2}, {4, 1, 5, 3}, {4, 0, 7, 2}, {5, 0, 8, 2}, {6, 1, 7, 3}, {7, 1, 8, 3} }; test_mode = _test_mode; - moves_left = test_mode ? INT_MAX : DEFAULT_MOVES; + moves_left = test_mode ? INT_MAX : _steps; for (int i = 0; i < MAZE_SIZE; ++i) { graph[i] = std::vector(DIRECTIONS, true); diff --git a/src/server/server.cpp b/src/server/server.cpp index 1eebd45..bd7074d 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -1,13 +1,21 @@ #include "server.hpp" -Server::Server(const std::string& h, const unsigned short p, bool service_mode){ - // Создание сокета. - server_fd = socket(AF_INET, SOCK_STREAM, 0); - if (server_fd < 0) { +bool Server::check_status(Maze &maze) { + return (!maze.test_mode && maze.get_moves_left() > 0); +} + +Server::Server(const std::string& h, const unsigned short p, bool _service){ + service_mode = _service; + if (service_mode) { + std::cout << "Service mode is ON" << std::endl; + } + + sockaddr_in server_address; + + if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { throw std::runtime_error("Error in create socket"); } - // Подготовка сетевого адреса для связывания. - sockaddr_in server_address; + memset(reinterpret_cast(&server_address), '\0', sizeof(server_address)); server_address.sin_family = AF_INET; hostent* host_name; @@ -15,36 +23,32 @@ Server::Server(const std::string& h, const unsigned short p, bool service_mode){ if (host_name == nullptr) { throw std::runtime_error("Error in getting hostname"); } + server_address.sin_port = htons(p); memcpy(&server_address.sin_addr.s_addr, host_name->h_addr, host_name->h_length); - if (bind(server_fd, reinterpret_cast(&server_address), sizeof(server_address)) != 0) { + if (bind(server_socket, reinterpret_cast(&server_address), sizeof(server_address)) != 0) { throw std::runtime_error("Error in bind part"); } std::cout << "Сервер запущен на хосте " << h << " на порту " << p << std::endl; } -bool Server::check_status(Maze &maze) { - return (!maze.test_mode && maze.get_moves_left() > 0); -} - -void Server::handle_client(int client_socket, bool mode) { - Maze maze(mode); // Создаем экземпляр лабиринта для клиента - int current_position = 0; // Начальная позиция игрока +void Server::handle_client(int client_socket, bool mode, int steps) { + Maze maze(mode, steps); + int current_position = 0; std::string player_name; - char buffer[1024] = {0}; + char buffer[BUFFER_SIZE] = {0}; std::string response; - // Получение имени игрока int bytes_received = recv(client_socket, buffer, sizeof(buffer), 0); if (bytes_received <= 0) { - std::cout << "Ошибка получения имени игрока.\n"; + std::cout << "Error in getting player name"; close(client_socket); return; } player_name = std::string(buffer); - std::cout << "Новый игрок: " << player_name << "\n"; + std::cout << "Новый игрок: " << player_name << std::endl; while (true) { int moves_left = maze.get_moves_left(); @@ -56,7 +60,7 @@ void Server::handle_client(int client_socket, bool mode) { } std::string command(buffer); - std::cout << "Получена команда от игрока " << player_name << ": " << command << "\n"; + std::cout << "Получена команда от игрока " << player_name << ": " << command << std::endl; int direction = -1; int new_position = current_position; @@ -109,10 +113,13 @@ void Server::handle_client(int client_socket, bool mode) { break; } + maze.set_moves_left(moves_left - 1); + if (!check_status(maze)) + break; + int x = current_position % 3; int y = current_position / 3; std::string text("(" + std::to_string(x) + ", " + std::to_string(y) + ")\n"); - maze.set_moves_left(moves_left - 1); response = "успешно, осталось " + std::to_string(maze.get_moves_left()) + " ходов. Вы находитесь в " + text; send(client_socket, response.c_str(), response.size(), 0); } @@ -124,25 +131,24 @@ void Server::handle_client(int client_socket, bool mode) { } close(client_socket); - std::cout << "Игрок " << player_name << " отключился.\n"; + std::cout << "Игрок " << player_name << " отключился" << std::endl; } -void Server::start() { +void Server::start(int steps) { int new_socket; - if (listen(server_fd, MAX_CLIENTS) < 0) { + if (listen(server_socket, MAX_CLIENTS) < 0) { throw std::runtime_error("Error in listen"); } sockaddr address; - int addrlen = sizeof(address); socklen_t address_size = sizeof(address); while (true) { - if ((new_socket = accept(server_fd, (struct sockaddr*)&address, &address_size)) < 0) { + if ((new_socket = accept(server_socket, (struct sockaddr*)&address, &address_size)) < 0) { throw std::runtime_error("Error in accept"); } - std::cout << "Новое соединение установлено.\n"; - std::thread(&Server::handle_client, this, new_socket, true).detach(); + std::cout << "Новое соединение установлено" << std::endl; + std::thread(&Server::handle_client, this, new_socket, service_mode, steps).detach(); } } \ No newline at end of file diff --git a/src/server/server_main.cpp b/src/server/server_main.cpp index dc79331..e751b97 100644 --- a/src/server/server_main.cpp +++ b/src/server/server_main.cpp @@ -3,10 +3,11 @@ int main(int argc, char **argv) { int opt; std::string host = "localhost"; + int steps = 10; bool service_mode = false; short unsigned port = 1024u; - while ((opt = getopt(argc, argv, "h:p:s:")) != -1) { + while ((opt = getopt(argc, argv, "h:p:sn:")) != -1) { switch (opt) { case 'h': host = optarg; @@ -14,8 +15,16 @@ int main(int argc, char **argv) { case 'p': port = static_cast(atoi(optarg)); break; + case 'n': + steps = atoi(optarg); + if(steps <= 0) { + std::cerr << "Invalid steps" << std::endl; + return 1; + } + break; case 's': service_mode = true; + break; default: break; } @@ -23,7 +32,7 @@ int main(int argc, char **argv) { try { Server server(host, port, service_mode); - server.start(); + server.start(steps); } catch (const std::runtime_error& e){ std::cerr << "Server application error: " << e.what() << std::endl; return 1; From 87eff113373ec78e19a9adfbaa27ce43be809f74 Mon Sep 17 00:00:00 2001 From: ParkSuMin Date: Wed, 30 Apr 2025 19:36:26 +0300 Subject: [PATCH 7/7] Update CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d4b15b..7914164 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ project(maze LANGUAGES CXX) set(CMAKE_CXX_STANDARD 23) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++23") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++23 -Wall") include_directories( include