Choose hostname and port (for server and client part)

This commit is contained in:
2025-04-30 15:14:10 +03:00
parent cc1bb79633
commit 3b84aa7740
6 changed files with 88 additions and 45 deletions

View File

@@ -6,16 +6,15 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <unistd.h> #include <unistd.h>
#include <netdb.h>
const int PORT = 8080;
class Client{ class Client{
private: private:
int sock; int sock;
public: public:
Client() : sock(0){}; Client();
void run(); void run(const std::string& h = "localhost", const unsigned short p = 1024u);
int ping(struct sockaddr_in); int ping(struct sockaddr_in);
void game();
}; };
#endif #endif

View File

@@ -7,11 +7,11 @@
#include <thread> #include <thread>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netdb.h>
#include <unistd.h> #include <unistd.h>
#include <cstring> #include <cstring>
const int PORT = 8080; const int MAX_CLIENTS = 512;
const int MAX_CLIENTS = 100;
class Server { class Server {
private: private:
@@ -20,7 +20,7 @@ private:
bool check_status(Maze& maze); bool check_status(Maze& maze);
public: public:
Server() : service_mode(false){}; Server() : service_mode(false){};
void start(); // Запуск сервера void start(const std::string& h = "localhost", const unsigned short p = 1024u); // Запуск сервера
}; };
#endif #endif

View File

@@ -11,28 +11,33 @@ void print_instructions() {
} }
int Client::ping(struct sockaddr_in address){ 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() { Client::Client(){
struct sockaddr_in serv_addr;
// Создание сокета // Создание сокета
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
throw std::runtime_error("[Client::request] connect(2) call error"); 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_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Преобразование IP-адреса из текстового вида в бинарный hostent* host_name;
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { host_name = gethostbyname(h.c_str()); // Преобразование названия хоста в IP-адрес.
throw std::runtime_error("[Client::request] connect(2) call error"); 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)) { if (ping(serv_addr)) {
throw std::runtime_error("Connection lost!"); throw std::runtime_error("Invalid hostname:port");
} }
std::cout << "Подключено к серверу. Введите ваше имя: "; std::cout << "Подключено к серверу. Введите ваше имя: ";
@@ -44,8 +49,10 @@ void Client::run() {
} }
// Отправка имени игрока на сервер // Отправка имени игрока на сервер
send(sock, player_name.c_str(), player_name.size(), 0); send(sock, player_name.c_str(), player_name.size(), 0);
std::cout << "Игра началась!\n"; }
void Client::game(){
std::cout << "Игра началась!\n";
print_instructions(); print_instructions();
char buffer[1024] = {0}; char buffer[1024] = {0};
@@ -74,6 +81,5 @@ void Client::run() {
break; break;
} }
} }
close(sock); close(sock);
} }

View File

@@ -1,9 +1,27 @@
#include "client.hpp" #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<unsigned short>(atoi(optarg));
break;
default:
break;
}
}
try { try {
Client client; Client client;
client.run(); client.run(host, port);
client.game();
} catch (const std::runtime_error& e){ } catch (const std::runtime_error& e){
std::cerr << "Client application error: " << e.what() << std::endl; std::cerr << "Client application error: " << e.what() << std::endl;
return 1; return 1;

View File

@@ -15,7 +15,7 @@ void Server::handle_client(int client_socket, bool mode) {
// Получение имени игрока // Получение имени игрока
int bytes_received = recv(client_socket, buffer, sizeof(buffer), 0); int bytes_received = recv(client_socket, buffer, sizeof(buffer), 0);
if (bytes_received <= 0) { if (bytes_received <= 0) {
std::cerr << "Ошибка получения имени игрока.\n"; std::cout << "Ошибка получения имени игрока.\n";
close(client_socket); close(client_socket);
return; return;
} }
@@ -104,42 +104,37 @@ void Server::handle_client(int client_socket, bool mode) {
std::cout << "Игрок " << player_name << " отключился.\n"; std::cout << "Игрок " << player_name << " отключился.\n";
} }
void Server::start() { void Server::start(const std::string& h, const unsigned short p) {
int server_fd, new_socket; int server_fd, new_socket;
struct sockaddr_in address; struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("Ошибка создания сокета"); throw std::runtime_error("Error in socket");
exit(EXIT_FAILURE);
}
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("Ошибка настройки сокета");
exit(EXIT_FAILURE);
} }
address.sin_family = AF_INET; address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY; hostent* host_name;
address.sin_port = htons(PORT); 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) { if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) != 0) {
perror("Ошибка привязки сокета"); throw std::runtime_error("Error in bind");
exit(EXIT_FAILURE);
} }
if (listen(server_fd, MAX_CLIENTS) < 0) { if (listen(server_fd, MAX_CLIENTS) < 0) {
perror("Ошибка прослушивания"); throw std::runtime_error("Error in listen");
exit(EXIT_FAILURE);
} }
std::cout << "Сервер запущен на порту " << PORT << "\n"; std::cout << "Сервер запущен на хосте " << h << " на порту " << p << std::endl;
int addrlen = sizeof(address);
while (true) { while (true) {
if ((new_socket = accept(server_fd, (struct sockaddr*)&address, (socklen_t*)&addrlen)) < 0) { if ((new_socket = accept(server_fd, (struct sockaddr*)&address, (socklen_t*)&addrlen)) < 0) {
perror("Ошибка принятия соединения"); throw std::runtime_error("Error in accept");
exit(EXIT_FAILURE);
} }
std::cout << "Новое соединение установлено.\n"; std::cout << "Новое соединение установлено.\n";

View File

@@ -1,9 +1,34 @@
#include "server.hpp" #include "server.hpp"
int main(int argc, char **argv) { int main(int argc, char **argv) {
int opt;
Server server; std::string host = "localhost";
server.start(); short unsigned port = 1024u;
while ((opt = getopt(argc, argv, "h:p:")) != -1) {
switch (opt) {
case 'h':
host = optarg;
break;
case 'p':
port = static_cast<unsigned short>(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; return 0;
} }