32#ifndef _POSIX_C_SOURCE
34#define _POSIX_C_SOURCE 200809L
43#include <sys/socket.h>
81template <
typename TParams>
96 std::unique_ptr<SocketThreadPool> pool_;
97 std::vector<char> buffer_;
100 template <
typename Params>
112 static void socket_proc(Task<Params> task) {
113 task.server->dispatch_socket(task.sock);
133 std::is_base_of_v<SocketServerParams, Params>,
134 "Not derived from tec::SocketServerParams class");
196 std::thread polling_thread([
this] {
201 polling_thread.join();
208 pool_.reset(
nullptr);
225 return buffer_.data();
240 TEC_ENTER(
"SocketServer::set_socket_options");
243 if( ::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
244 &
params_.opt_reuse_addr,
sizeof(
int)) < 0 ) {
253 if (::setsockopt(fd, SOL_SOCKET, SO_REUSEPORT,
254 &
params_.opt_reuse_port,
sizeof(
int)) < 0) {
274 char client_ip[INET6_ADDRSTRLEN];
278 if (client_addr->ss_family == AF_INET) {
280 struct sockaddr_in *s = (
struct sockaddr_in*)&client_addr;
281 ::inet_ntop(AF_INET, &s->sin_addr, client_ip,
sizeof(client_ip));
282 client_port = ::ntohs(s->sin_port);
284 else if (client_addr->ss_family == AF_INET6) {
286 struct sockaddr_in6 *s = (
struct sockaddr_in6*)&client_addr;
287 ::inet_ntop(AF_INET6, &s->sin6_addr, client_ip,
sizeof(client_ip));
288 client_port = ::ntohs(s->sin6_port);
300 TEC_ENTER(
"SocketServer::resolve_and_bind_host");
305 ::memset(&hints, 0,
sizeof(hints));
306 hints.ai_family =
params_.family;
307 hints.ai_socktype =
params_.socktype;
308 hints.ai_protocol =
params_.protocol;
312 addrinfo* servinfo{NULL};
314 ::snprintf(port_str, 15,
"%d",
params_.port);
315 int ecode = ::getaddrinfo(
params_.addr.c_str(), port_str,
318 std::string emsg{::gai_strerror(ecode)};
319 TEC_TRACE(
"Address resolving error: {}", emsg);
329 for (p = servinfo ; p != NULL ; p = p->ai_next) {
330 fd = ::socket(p->ai_family, p->ai_socktype, p->ai_protocol);
338 if (!option_status) {
341 ::freeaddrinfo(servinfo);
342 return option_status;
345 if (::bind(fd, p->ai_addr, p->ai_addrlen) != -1) {
355 ::freeaddrinfo(servinfo);
373 TEC_ENTER(
"SocketServer::start_listening");
391 TEC_ENTER(
"SocketServer::accept_connection");
393 socklen_t sin_size =
sizeof(sockaddr_storage);
395 (sockaddr *)client_addr,
400 if( errno == EINVAL || errno == EINTR || errno == EBADF ) {
401 err_msg =
format(
"Polling interrupted by signal {}.", errno);
404 err_msg =
format(
"accept() failed with errno={}.", errno);
426 sockaddr_storage client_addr;
427 TEC_TRACE(
"Waiting for incoming connection...");
435 if (sock.
port == -1) {
460 size_t idx = pool_->get_next_worker_index();
463 sock.
buffer = pool_->get_buffer(idx);
466 Task<Params> task{
this, sock};
467 pool_->enqueue([task] {
468 details::socket_proc(task);
485 TEC_ENTER(
"SocketServer::dispatch_socket");
501 TEC_ENTER(
"SocketServer::close_client_connection");
503 if (sock->
fd != -1) {
518 TEC_ENTER(
"SocketServer::on_char_stream");
Abstract base class defining the actor lifecycle and request handling interface.
Definition tec_actor.hpp:63
A byte buffer class with stream-like read/write semantics.
Definition tec_memfile.hpp:50
A thread-safe signal mechanism for inter-thread synchronization.
Definition tec_signal.hpp:44
void set()
Sets the signal to the signaled state and notifies all waiting threads.
Definition tec_signal.hpp:72
void wait() const
Waits indefinitely until the signal is set.
Definition tec_signal.hpp:85
Generic BSD socket server template using actor pattern with configurable parameters.
Definition tec_socket_server.hpp:82
virtual void process_socket(Socket sock)
Decides how to handle newly accepted client socket.
Definition tec_socket_server.hpp:456
void shutdown(Signal *sig_stopped) override
Gracefully shuts down the server.
Definition tec_socket_server.hpp:190
virtual Status accept_connection(int *clientfd, sockaddr_storage *client_addr)
Accepts one incoming connection (blocking)
Definition tec_socket_server.hpp:390
virtual void on_net_data(const Socket *sock)
Default handler for binary / structured network protocols.
Definition tec_socket_server.hpp:533
virtual ~SocketServer()=default
Virtual destructor (default implementation)
TParams Params
Parameter type — must inherit from tec::SocketServerParams
Definition tec_socket_server.hpp:85
constexpr char * get_buffer()
Definition tec_socket_server.hpp:224
Status process_request(Request request, Reply reply) override
Default request processor (not used in socket server)
Definition tec_socket_server.hpp:218
virtual void dispatch_socket(Socket _sock)
Executes client connection handling logic.
Definition tec_socket_server.hpp:484
Signal polling_stopped_
Signal object set when polling loop has fully exited.
Definition tec_socket_server.hpp:92
constexpr size_t get_buffer_size() const
Definition tec_socket_server.hpp:229
SocketServer(const Params ¶ms)
Constructs server instance with given parameters.
Definition tec_socket_server.hpp:125
void start(Signal *sig_started, Status *status) override
Starts the server: bind → listen → accept loop.
Definition tec_socket_server.hpp:147
virtual Socket get_socket_info(int client_fd, sockaddr_storage *client_addr)
Creates Socket object from raw file descriptor and peer address.
Definition tec_socket_server.hpp:273
virtual Status set_socket_options(int fd)
Sets common socket options (SO_REUSEADDR, SO_REUSEPORT)
Definition tec_socket_server.hpp:239
virtual Status resolve_and_bind_host()
Resolves address/port and binds listening socket.
Definition tec_socket_server.hpp:299
std::atomic_bool stop_polling_
Atomic flag used to signal the acceptor/polling loop to exit.
Definition tec_socket_server.hpp:91
int listenfd_
Listening socket file descriptor (-1 when not bound/listening)
Definition tec_socket_server.hpp:90
virtual void close_client_connection(Socket *sock)
Closes client connection cleanly.
Definition tec_socket_server.hpp:500
Params params_
Server configuration parameters (address, port, buffer size, threading mode, etc.)
Definition tec_socket_server.hpp:89
virtual void on_string(const Socket *sock)
Default handler for character-stream / line-based protocols.
Definition tec_socket_server.hpp:517
virtual void poll(Signal *sig_started)
Main acceptor loop — runs until stop_polling_ is set.
Definition tec_socket_server.hpp:417
virtual Status start_listening()
Starts listening on the bound socket.
Definition tec_socket_server.hpp:372
#define TEC_ENTER(name)
Logs an entry message for a named context (e.g., function).
Definition tec_trace.hpp:211
#define TEC_TRACE(...)
Logs a formatted trace message.
Definition tec_trace.hpp:222
@ NetErr
Network-related error.
@ NotImplemented
Not implemented.
static constexpr int kModeNetData
Treat incoming data as length-prefixed binary network messages.
Definition tec_socket.hpp:182
static constexpr int kModeCharStream
Treat incoming data as null-terminated character streams.
Definition tec_socket.hpp:179
Lightweight wrapper around a connected socket file descriptor.
Definition tec_socket.hpp:272
static Status recv(Bytes &data, const Socket *sock, size_t length)
Receive data from a socket into a MemFile (Bytes).
Definition tec_socket.hpp:329
static Status send(const Bytes &data, const Socket *sock)
Send the entire contents of a MemFile (Bytes) through a socket.
Definition tec_socket.hpp:395
char * buffer
Buffer used in send/recv operations.
Definition tec_socket.hpp:276
int port
Peer port number.
Definition tec_socket.hpp:275
size_t buffer_size
Size of the buffer.
Definition tec_socket.hpp:277
int fd
Underlying socket file descriptor.
Definition tec_socket.hpp:273
char addr[INET6_ADDRSTRLEN]
Peer address as a null-terminated string (IPv4 or IPv6).
Definition tec_socket.hpp:274
constexpr bool ok() const
Checks if the status indicates success.
Definition tec_status.hpp:120
Core interface for TEC actors with lifecycle management and request processing.
Common definitions and utilities for the tec namespace.
A byte buffer class with stream-like read/write semantics.
std::any Reply
Type alias for a reply object that can hold any object.
Definition tec_message.hpp:55
std::any Request
Type alias for a request object that can hold any object.
Definition tec_message.hpp:49
std::string format(const T &arg)
Formats a single argument into a string.
Definition tec_print.hpp:171
Defines a thread-safe signal implementation using mutex and condition variable.
Generic BSD socket parameters and helpers.
Specialized thread pool that maintains one pre-allocated fixed-size buffer per worker thread.
Defines error handling types and utilities for the tec namespace.
Provides a thread-safe tracing utility for debugging in the tec namespace.