succeffully spun up threads to answer clients, just have to client-side comms next.

This commit is contained in:
2025-10-25 00:13:23 -05:00
parent 0f62d80ffb
commit da73d88dd0
8 changed files with 138 additions and 17 deletions

View File

@@ -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()

View File

@@ -1,25 +1,48 @@
#include "socket-manager.hpp"
#include "json_fwd.hpp"
#include "spdlog/spdlog.h"
#include <netinet/in.h>
#include <string>
#include <sys/socket.h>
#include <thread>
#include <unistd.h>
#include <vector>
#include "../shared-utils/objects.hpp"
#include "../shared-utils/socket-utils.hpp"
#include <cstdint>
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<char>{};
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);
}
}

View File

@@ -2,5 +2,9 @@
#include <sys/socket.h>
#include <cstdint>
#include <netinet/in.h>
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);
}

View File

@@ -4,6 +4,8 @@
#include <filesystem>
#include <iostream>
#include <toml++/toml.hpp>
#include <unistd.h>
#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;
}

View File

@@ -1,7 +1,11 @@
#include "objects.hpp"
#include "json_fwd.hpp"
namespace serializable {
template <typename S>
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);
}
}

View File

@@ -1,5 +1,5 @@
#pragma once
#include <nlohmann/json.hpp>
#include <cstdint>
namespace serializable{
@@ -8,6 +8,7 @@ struct HandshakeConnection {
std::uint16_t payload;
};
template<typename S>
void serialize(S& s, HandshakeConnection& object);
void to_json(nlohmann::json& j, const HandshakeConnection& handshake );
void from_json(const nlohmann::json& j, HandshakeConnection& handshake );
}

View File

@@ -0,0 +1,29 @@
#include <vector>
#include <sys/socket.h>
#include <algorithm>
#include "socket-utils.hpp"
namespace socket_utils {
ssize_t write_to_socket(int sock_fd, std::vector<char>& 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<char>& 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;
}
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include <vector>
#include <sys/socket.h>
namespace socket_utils{
ssize_t write_to_socket(int sock_fd, std::vector<char>& write_buffer);
ssize_t read_from_socket(int sock_fd, std::vector<char>& read_buffer);
}