initial commit
This commit is contained in:
commit
1ee3a9863c
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@ -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
|
||||
17
CMakeLists.txt
Normal file
17
CMakeLists.txt
Normal file
@ -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})
|
||||
|
||||
1
config.ini
Normal file
1
config.ini
Normal file
@ -0,0 +1 @@
|
||||
address 127.0.0.1
|
||||
56
src/config.cpp
Normal file
56
src/config.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include "config.hpp"
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
22
src/config.hpp
Normal file
22
src/config.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
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);
|
||||
};
|
||||
22
src/main.cpp
Normal file
22
src/main.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include <iostream>
|
||||
#include <csignal>
|
||||
#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;
|
||||
}
|
||||
73
src/server.cpp
Normal file
73
src/server.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include "server.hpp"
|
||||
#include <iostream>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
20
src/server.hpp
Normal file
20
src/server.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#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();
|
||||
};
|
||||
9
src/utils.cpp
Normal file
9
src/utils.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
void stop_program(int signum) {
|
||||
std::cout << "\nInterrupt signal (" << signum << ") received.\n";
|
||||
std::cout << "Exiting program...\n";
|
||||
exit(signum);
|
||||
}
|
||||
6
src/utils.hpp
Normal file
6
src/utils.hpp
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
void stop_program(int signum);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user