From 5b870db2cf87215bf12cb96b98dd626700c9239e Mon Sep 17 00:00:00 2001 From: theokyr Date: Sun, 7 Jul 2024 07:04:26 +0300 Subject: [PATCH] feat(server): added port param `-p` and added best binding best effort mechanism (port+1 forever) --- CS2RemoteConsole-server/src/main.cpp | 17 ++++++- CS2RemoteConsole-server/src/server.cpp | 67 +++++++++++++++++++------- CS2RemoteConsole-server/src/server.h | 4 +- 3 files changed, 68 insertions(+), 20 deletions(-) diff --git a/CS2RemoteConsole-server/src/main.cpp b/CS2RemoteConsole-server/src/main.cpp index 5015a54..98871b5 100644 --- a/CS2RemoteConsole-server/src/main.cpp +++ b/CS2RemoteConsole-server/src/main.cpp @@ -2,6 +2,8 @@ #include "utils.h" #include #include +#include +#include std::atomic applicationRunning(true); @@ -11,11 +13,22 @@ void signalHandler(int signum) applicationRunning = false; } -int main() +int main(int argc, char* argv[]) { signal(SIGINT, signalHandler); signal(SIGTERM, signalHandler); + uint16_t port = 42069; // Default port + + for (int i = 1; i < argc; i++) + { + std::string arg = argv[i]; + if ((arg == "-p" || arg == "--port") && i + 1 < argc) + { + port = static_cast(std::atoi(argv[++i])); + } + } + #ifdef _WIN32 if (!initializeWinsock()) { @@ -24,7 +37,7 @@ int main() } #endif - Server server(42069, applicationRunning); + Server server(port, applicationRunning); if (!server.start()) { return 1; diff --git a/CS2RemoteConsole-server/src/server.cpp b/CS2RemoteConsole-server/src/server.cpp index 8481054..470220c 100644 --- a/CS2RemoteConsole-server/src/server.cpp +++ b/CS2RemoteConsole-server/src/server.cpp @@ -4,8 +4,8 @@ #include #include -Server::Server(uint16_t port, std::atomic& running) - : m_port(port), m_listenSocket(INVALID_SOCKET), m_running(running) +Server::Server(uint16_t initialPort, std::atomic& running) + : m_initialPort(initialPort), m_port(initialPort), m_listenSocket(INVALID_SOCKET), m_running(running) { } @@ -16,23 +16,52 @@ Server::~Server() bool Server::start() { - m_listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (m_listenSocket == INVALID_SOCKET) + const int MAX_PORT = 65535; // Maximum valid port number + + while (m_port <= MAX_PORT) { - std::cerr << "Error creating socket: " << SOCKET_ERROR_CODE << std::endl; - return false; - } + std::cout << "Attempting to bind to port " << m_port << "..." << std::endl; - sockaddr_in serverAddr{}; - serverAddr.sin_family = AF_INET; - serverAddr.sin_addr.s_addr = INADDR_ANY; - serverAddr.sin_port = htons(m_port); + m_listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (m_listenSocket == INVALID_SOCKET) + { + std::cerr << "Error creating socket: " << SOCKET_ERROR_CODE << std::endl; + return false; + } - if (bind(m_listenSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) - { - std::cerr << "Bind failed: " << SOCKET_ERROR_CODE << std::endl; - cleanupSockets(); - return false; + int opt = 1; + if (setsockopt(m_listenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt)) < 0) + { + std::cerr << "setsockopt(SO_REUSEADDR) failed: " << SOCKET_ERROR_CODE << std::endl; + cleanupSockets(); + return false; + } + + sockaddr_in serverAddr{}; + serverAddr.sin_family = AF_INET; + serverAddr.sin_addr.s_addr = INADDR_ANY; + serverAddr.sin_port = htons(m_port); + + if (bind(m_listenSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) + { + std::cerr << "Bind failed on port " << m_port << ": " << SOCKET_ERROR_CODE << std::endl; + + cleanupSockets(); + + // Try the next port + m_port++; + + if (m_port > MAX_PORT) + { + std::cerr << "Exhausted all available ports. Failed to start server." << std::endl; + return false; + } + + continue; + } + + // If we reach here, bind was successful + break; } if (listen(m_listenSocket, SOMAXCONN) == SOCKET_ERROR) @@ -44,7 +73,11 @@ bool Server::start() setNonBlocking(m_listenSocket); - std::cout << "Server is listening on port " << m_port << "..." << std::endl; + std::cout << "Server is listening on port " << m_port << std::endl; + if (m_port != m_initialPort) + { + std::cout << "Note: The server is using a different port than initially specified." << std::endl; + } return true; } diff --git a/CS2RemoteConsole-server/src/server.h b/CS2RemoteConsole-server/src/server.h index 321cfa1..39d74f8 100644 --- a/CS2RemoteConsole-server/src/server.h +++ b/CS2RemoteConsole-server/src/server.h @@ -10,13 +10,15 @@ class Server { public: - Server(uint16_t port, std::atomic& running); + Server(uint16_t initialPort, std::atomic& running); ~Server(); bool start(); void run(); + uint16_t getCurrentPort() const { return m_port; } private: + uint16_t m_initialPort; uint16_t m_port; SOCKET m_listenSocket; std::vector m_clients;