commit 1ee3a9863c06a1cbebe731810ed83fa386779f7c Author: Илья Глазунов Date: Fri Jan 9 16:37:47 2026 +0300 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6b7df28 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +CMakeCache.txt +CMakeFiles/ +Makefile +cmake_install.cmake +install_local_manifest.txt +install_manifest.txt +install_prefix.txt +install_strip.txt +install_strip_local.txt +install_strip_local_manifest.txt +install_strip_local_manifest.txt +.vscode/ + +my_own_redis \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..623ca27 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.10) + +project(MyOwnRedis) + + +set(CMAKE_CXX_STANDART 17) +set(CMAKE_CXX_REQUIRED ON) + +set(SOURCES + src/main.cpp + src/utils.cpp + src/config.cpp + src/server.cpp +) + +add_executable(my_own_redis ${SOURCES}) + diff --git a/config.ini b/config.ini new file mode 100644 index 0000000..fcc42ac --- /dev/null +++ b/config.ini @@ -0,0 +1 @@ +address 127.0.0.1 \ No newline at end of file diff --git a/src/config.cpp b/src/config.cpp new file mode 100644 index 0000000..61ab4f6 --- /dev/null +++ b/src/config.cpp @@ -0,0 +1,56 @@ +#include "config.hpp" +#include +#include +#include + +Config::Config(const std::string& filename) { + if (filename.empty()) { + std::cerr << "Filename is empty\nUsing default filename: config.ini\n"; + } + load_from_file(filename); + check_required_keys(); +} + +void Config::load_from_file(const std::string& filename) { + std::ifstream file(filename); + if (!file.is_open()) { + std::cerr << "Failed to open config file: " << filename << "\n"; + std::cout << "Using default parameters: 127.0.0.1:6379\n"; + address = "127.0.0.1"; + port = 6379; + return; + } + + std::string key; + while (file >> key) { + if (key == "address") { + file >> address; + } else if (key == "port") { + file >> port; + } else { + std::cerr << "Unknown key: " << key << "\n"; + continue; + } + } + + file.close(); +} + +std::string Config::get_address() const { + return address; +} + +int Config::get_port() const { + return port; +} + +void Config::check_required_keys() const { + if (address.empty()) { + std::cerr << "Address is not set\n"; + exit(EXIT_FAILURE); + } + if (port == 0 ) { + std::cerr << "Port is not set\n"; + exit(EXIT_FAILURE); + } +} diff --git a/src/config.hpp b/src/config.hpp new file mode 100644 index 0000000..5c5ebfb --- /dev/null +++ b/src/config.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +class Config { +public: + // Конструктор + Config(const std::string& filename = "config.ini"); + + // Геттеры + std::string get_address() const; + int get_port() const; + + void check_required_keys() const; + +private: + std::string address; + int port; + + void load_from_file(const std::string& filename); +}; diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..c4efaf8 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,22 @@ +#include +#include +#include "config.hpp" +#include "server.hpp" +#include "utils.hpp" + +int main() { + std::signal(SIGINT, stop_program); + + try { + Config config("config.ini"); + config.check_required_keys(); + + Server server(config); + server.run(); + } catch (const std::exception& e) { + std::cerr << "Fatal error: " << e.what() << "\n"; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/src/server.cpp b/src/server.cpp new file mode 100644 index 0000000..eabd1cd --- /dev/null +++ b/src/server.cpp @@ -0,0 +1,73 @@ +#include "server.hpp" +#include +#include +#include +#include +#include + +Server::Server(const Config& config) + : address(config.get_address()), port(config.get_port()), sockfd(-1) { +} + +Server::~Server() { + if (sockfd != -1) { + close(sockfd); + } +} + +void Server::setup() { + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd == -1) { + throw std::runtime_error("Error creating socket"); + } + + int val = 1; + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); + + sockaddr_in addr{}; + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + + if (inet_pton(AF_INET, address.c_str(), &addr.sin_addr) != 1) { + throw std::runtime_error("Error parsing address: " + address); + } + + if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + throw std::runtime_error("Error binding to " + address + ":" + std::to_string(port)); + } + + if (listen(sockfd, SOMAXCONN) < 0) { + throw std::runtime_error("Error listening for connections"); + } + + std::cout << "Server started on " << address << ":" << port << "\n"; +} + +void Server::handle_connection(int connectionfd) { + char rbuf[64] = {}; + ssize_t n = read(connectionfd, rbuf, sizeof(rbuf) - 1); + if (n < 0) { + std::cerr << "Error reading client packet\n"; + return; + } + std::cout << "Client says: " << std::string(rbuf, n) << "\n"; + ssize_t written = write(connectionfd, "Hello, client!\n", 14); + if (written < 0) { + std::cerr << "Error writing to client\n"; + } +} + +void Server::run() { + setup(); + + while (true) { + struct sockaddr_in client_addr = {}; + socklen_t addrlen = sizeof(client_addr); + int connectionfd = accept(sockfd, (struct sockaddr *)&client_addr, &addrlen); + if (connectionfd < 0) { + continue; + } + handle_connection(connectionfd); + close(connectionfd); + } +} diff --git a/src/server.hpp b/src/server.hpp new file mode 100644 index 0000000..e811495 --- /dev/null +++ b/src/server.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include +#include "config.hpp" + +class Server { +public: + Server(const Config& config); + ~Server(); + + void run(); + +private: + int sockfd; + std::string address; + int port; + + void handle_connection(int connectionfd); + void setup(); +}; diff --git a/src/utils.cpp b/src/utils.cpp new file mode 100644 index 0000000..1d0d4c0 --- /dev/null +++ b/src/utils.cpp @@ -0,0 +1,9 @@ +#include +#include +#include + +void stop_program(int signum) { + std::cout << "\nInterrupt signal (" << signum << ") received.\n"; + std::cout << "Exiting program...\n"; + exit(signum); +} diff --git a/src/utils.hpp b/src/utils.hpp new file mode 100644 index 0000000..9554f86 --- /dev/null +++ b/src/utils.hpp @@ -0,0 +1,6 @@ +#pragma once + +#include + +void stop_program(int signum); +