From da73d88dd0db3280242c9ef08f9e62812d6cd77a Mon Sep 17 00:00:00 2001 From: Mars Ultor Date: Sat, 25 Oct 2025 00:13:23 -0500 Subject: [PATCH] succeffully spun up threads to answer clients, just have to client-side comms next. --- CMakeLists.txt | 52 +++++++++++++++++++++++++---- src/daemon-utils/socket-manager.cpp | 31 ++++++++++++++--- src/daemon-utils/socket-manager.hpp | 8 +++-- src/main-daemon.cpp | 9 +++++ src/shared-utils/objects.cpp | 8 +++-- src/shared-utils/objects.hpp | 7 ++-- src/shared-utils/socket-utils.cpp | 29 ++++++++++++++++ src/shared-utils/socket-utils.hpp | 11 ++++++ 8 files changed, 138 insertions(+), 17 deletions(-) create mode 100644 src/shared-utils/socket-utils.cpp create mode 100644 src/shared-utils/socket-utils.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3fc3958..4cbedf8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,19 +5,30 @@ set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +# ----------------------------- # Dependencies +# ----------------------------- add_subdirectory(external/fmt) add_subdirectory(external/spdlog) add_subdirectory(external/tomlplusplus) add_subdirectory(external/duckdb) add_subdirectory(external/json) + +# ----------------------------- # Executables +# ----------------------------- add_executable(${PROJECT_NAME}-client src/main-tracker.cpp) add_executable(${PROJECT_NAME}-daemon src/main-daemon.cpp) -# Common targets +# ----------------------------- +# Common libraries +# ----------------------------- set(COMMON_LIBS fmt spdlog tomlplusplus duckdb_static nlohmann_json) -set(COMMON_INCLUDES + +# ----------------------------- +# External includes +# ----------------------------- +set(EXTERNAL_INCLUDES external/fmt/include external/spdlog/include external/tomlplusplus/include @@ -25,9 +36,38 @@ set(COMMON_INCLUDES external/json/include/nlohmann ) -# Apply common settings -foreach(target ${PROJECT_NAME}-client ${PROJECT_NAME}-daemon) - target_link_libraries(${target} PRIVATE ${COMMON_LIBS}) - target_include_directories(${target} PRIVATE ${COMMON_INCLUDES}) +# ----------------------------- +# Automatically include all header directories under src/ +# ----------------------------- +file(GLOB_RECURSE SRC_SUBDIRS LIST_DIRECTORIES true "${CMAKE_CURRENT_SOURCE_DIR}/src/*") +set(SRC_INCLUDES "") +foreach(dir ${SRC_SUBDIRS}) + if(IS_DIRECTORY ${dir}) + list(APPEND SRC_INCLUDES ${dir}) + endif() +endforeach() + +# ----------------------------- +# Automatically include all .cpp under src/ +# Exclude main files to avoid multiple main() definitions +# ----------------------------- +file(GLOB_RECURSE ALL_CPP "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +list(REMOVE_ITEM ALL_CPP + "${CMAKE_CURRENT_SOURCE_DIR}/src/main-tracker.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/src/main-daemon.cpp" +) + +# ----------------------------- +# Apply to targets +# ----------------------------- +foreach(target ${PROJECT_NAME}-client ${PROJECT_NAME}-daemon) + # Link common libraries + target_link_libraries(${target} PRIVATE ${COMMON_LIBS}) + + # Include directories + target_include_directories(${target} PRIVATE ${EXTERNAL_INCLUDES} ${SRC_INCLUDES}) + + # Add all .cpp sources dynamically + target_sources(${target} PRIVATE ${ALL_CPP}) endforeach() diff --git a/src/daemon-utils/socket-manager.cpp b/src/daemon-utils/socket-manager.cpp index 8759962..48f59f1 100644 --- a/src/daemon-utils/socket-manager.cpp +++ b/src/daemon-utils/socket-manager.cpp @@ -1,25 +1,48 @@ #include "socket-manager.hpp" +#include "json_fwd.hpp" +#include "spdlog/spdlog.h" #include +#include #include #include +#include +#include +#include "../shared-utils/objects.hpp" +#include "../shared-utils/socket-utils.hpp" +#include -void start_daemon(std::uint16_t port){ +namespace socket_manager { + void start_daemon(std::uint16_t port){ int server_socket = socket(AF_INET, SOCK_STREAM, 0); sockaddr_in server_address; server_address.sin_family = AF_INET; - server_address.sin_port = htons(8080); + server_address.sin_port = htons(port); server_address.sin_addr.s_addr = INADDR_ANY; bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address)); - + spdlog::debug("port bound, server socket: {}", server_socket); // listening to the assigned socket listen(server_socket, 5); while(true){ int client_socket = accept(server_socket, nullptr,nullptr); + spdlog::info("new socket created"); std::thread client_handling_thread = std::thread{handle_client, client_socket}; + client_handling_thread.detach(); + spdlog::debug("new thread spun up, returning to main loop"); } } void handle_client(int client_socket){ - + std::vector buffer = std::vector{}; + serializable::HandshakeConnection prelim_handshake = serializable::HandshakeConnection{.payload = 123}; + nlohmann::json to_dump_handshake = prelim_handshake; + { + std::string dumped_handshake = to_dump_handshake.dump(); + buffer.insert(buffer.end(), dumped_handshake.begin(), dumped_handshake.end()); + socket_utils::write_to_socket(client_socket, buffer); + } + shutdown(client_socket, SHUT_RDWR); + close(client_socket); + spdlog::debug("Connection closed gracefully {}", client_socket); +} } diff --git a/src/daemon-utils/socket-manager.hpp b/src/daemon-utils/socket-manager.hpp index 8ba68de..1f5f454 100644 --- a/src/daemon-utils/socket-manager.hpp +++ b/src/daemon-utils/socket-manager.hpp @@ -2,5 +2,9 @@ #include #include #include -void handle_client(int client_socket); -void start_daemon(std::uint16_t port); + +namespace socket_manager { + void handle_client(int client_socket); + void start_daemon(std::uint16_t port); +} + diff --git a/src/main-daemon.cpp b/src/main-daemon.cpp index a16b4f3..2b2e2f0 100644 --- a/src/main-daemon.cpp +++ b/src/main-daemon.cpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include "daemon-utils/socket-manager.hpp" // This is the *daemon* int main() { @@ -21,6 +23,13 @@ int main() { spdlog::debug("Path collected: {}", http_server_fqdn); spdlog::debug("Port collected for inter-process communication {}", inter_comm_port); + + std::thread socket_management_root = std::thread{socket_manager::start_daemon, inter_comm_port}; + spdlog::info("socket management thread started and detached"); + while (true) { + sleep(100); + spdlog::debug("Status of socket management thread: {}", socket_management_root.joinable()); + } return 0; } diff --git a/src/shared-utils/objects.cpp b/src/shared-utils/objects.cpp index fe086be..67fa69d 100644 --- a/src/shared-utils/objects.cpp +++ b/src/shared-utils/objects.cpp @@ -1,7 +1,11 @@ #include "objects.hpp" +#include "json_fwd.hpp" namespace serializable { - template - void serialize(S &s, HandshakeConnection &object){ + void to_json(nlohmann::json &j, const HandshakeConnection &handshake){ + j = nlohmann::json{{"payload", handshake.payload}}; +} + void from_json(const nlohmann::json &j, HandshakeConnection &handshake){ + j.at("payload").get_to(handshake.payload); } } diff --git a/src/shared-utils/objects.hpp b/src/shared-utils/objects.hpp index 8588f8e..1471182 100644 --- a/src/shared-utils/objects.hpp +++ b/src/shared-utils/objects.hpp @@ -1,5 +1,5 @@ #pragma once - +#include #include namespace serializable{ @@ -8,6 +8,7 @@ struct HandshakeConnection { std::uint16_t payload; }; - template - void serialize(S& s, HandshakeConnection& object); + void to_json(nlohmann::json& j, const HandshakeConnection& handshake ); + + void from_json(const nlohmann::json& j, HandshakeConnection& handshake ); } diff --git a/src/shared-utils/socket-utils.cpp b/src/shared-utils/socket-utils.cpp new file mode 100644 index 0000000..eb1e56a --- /dev/null +++ b/src/shared-utils/socket-utils.cpp @@ -0,0 +1,29 @@ +#include +#include +#include +#include "socket-utils.hpp" + +namespace socket_utils { + ssize_t write_to_socket(int sock_fd, std::vector& write_buffer) { + if (write_buffer.empty()) return 0; + + char temp[4096]; + size_t to_write = std::min(write_buffer.size(), sizeof(temp)); + std::copy(write_buffer.begin(), write_buffer.begin() + to_write, temp); + + ssize_t bytes_sent = send(sock_fd, temp, to_write, 0); + if (bytes_sent > 0) { + write_buffer.erase(write_buffer.begin(), write_buffer.begin() + bytes_sent); + } + return bytes_sent; +} +ssize_t read_from_socket(int sock_fd, std::vector& read_buffer) { + char temp[4096]; // local buffer, destroyed when function exits + ssize_t bytes_read = recv(sock_fd, temp, sizeof(temp), 0); + if (bytes_read > 0) { + read_buffer.insert(read_buffer.end(), temp, temp + bytes_read); + } + return bytes_read; +} +} + diff --git a/src/shared-utils/socket-utils.hpp b/src/shared-utils/socket-utils.hpp new file mode 100644 index 0000000..15c3cb6 --- /dev/null +++ b/src/shared-utils/socket-utils.hpp @@ -0,0 +1,11 @@ +#pragma once +#include +#include + +namespace socket_utils{ + + ssize_t write_to_socket(int sock_fd, std::vector& write_buffer); + + ssize_t read_from_socket(int sock_fd, std::vector& read_buffer); + +}