2026-09-08 10:35:16 +08:00
|
|
|
#ifndef INCLUDED_C_TCPSERVER_H
|
|
|
|
|
#define INCLUDED_C_TCPSERVER_H
|
|
|
|
|
|
|
|
|
|
#ifndef INCLUDED_C_TYPES_H
|
|
|
|
|
#include <c_Types.h>
|
|
|
|
|
#endif /*INCLUDED_C_TYPES_H*/
|
|
|
|
|
|
|
|
|
|
#ifndef INCLUDED_C_ALLOCATOR_H
|
|
|
|
|
#include <c_Allocator.h>
|
|
|
|
|
#endif /*INCLUDED_C_ALLOCATOR_H*/
|
|
|
|
|
|
|
|
|
|
#ifndef INCLUDED_C_INSTREAM_H
|
|
|
|
|
#include <c_InStream.h>
|
|
|
|
|
#endif /*INCLUDED_C_INSTREAM_H*/
|
|
|
|
|
|
|
|
|
|
#ifndef INCLUDED_C_OUTSTREAM_H
|
|
|
|
|
#include <c_OutStream.h>
|
|
|
|
|
#endif /*INCLUDED_C_OUTSTREAM_H*/
|
|
|
|
|
|
|
|
|
|
#ifndef INCLUDED_C_SOCKET_H
|
|
|
|
|
#include <c_Socket.h>
|
|
|
|
|
#endif /*INCLUDED_C_SOCKET_H*/
|
|
|
|
|
|
|
|
|
|
#ifndef INCLUDED_C_SOCKETUTIL_H
|
|
|
|
|
#include <c_SocketUtil.h>
|
|
|
|
|
#endif /*INCLUDED_C_SOCKETUTIL_H*/
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
|
|
|
/* */
|
|
|
|
|
|
|
|
|
|
#define C_TCPSERVER_ERR_ON_POLL 1001
|
|
|
|
|
#define C_TCPSERVER_ERR_ON_ACCEPT 1002
|
|
|
|
|
#define C_TCPSERVER_ERR_ON_POLLERR 1003
|
|
|
|
|
#define C_TCPSERVER_ERR_ON_RECV 1004
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
|
|
|
/* */
|
|
|
|
|
|
|
|
|
|
typedef struct c_TcpServer_t c_TcpServer_t;
|
|
|
|
|
typedef struct c_TcpReactor_t c_TcpReactor_t;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Unified event-driven user callback signature.
|
|
|
|
|
* @param client_sock The accepted socket descriptor for the client.
|
|
|
|
|
* @param peer_addr Unified dual-stack address structure containing client peer details.
|
|
|
|
|
*/
|
|
|
|
|
typedef bool (*c_TcpServer_OnConnect_t)(c_TcpServer_t* server, c_socket_t client_sock, const c_SockAddr_t* peer_addr, void* args);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Event-driven user data processing callback matched exactly to your layout signature.
|
|
|
|
|
* @param s The raw socket descriptor exhibiting unread data availability.
|
|
|
|
|
* @return C_TRUE to keep monitoring the client; C_FALSE to break and close the connection.
|
|
|
|
|
*/
|
|
|
|
|
typedef bool (*c_TcpServer_OnRequest_t)(c_TcpServer_t* server, c_socket_t s, void* args);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Event-driven user callback fired whenever an active client disconnects or encounters an error.
|
|
|
|
|
* @param s The raw socket descriptor of the client being terminated.
|
|
|
|
|
* @param args Custom user context parameters pointer.
|
|
|
|
|
*/
|
|
|
|
|
typedef void (*c_TcpServer_OnDisconnect_t)(c_TcpServer_t* server, c_socket_t s, void* args);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Event-driven user callback fired whenever an operational network error is caught.
|
|
|
|
|
* @param s The socket descriptor associated with the failure (Can be server->listen_sock or a client handle).
|
|
|
|
|
* @param error_code Internal unified framework error mapping code.
|
|
|
|
|
* @param args Custom user context parameters pointer.
|
|
|
|
|
*/
|
|
|
|
|
typedef void (*c_TcpServer_OnError_t)(c_TcpServer_t* server, c_socket_t s, c_err_t error_code, void* args);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Virtual Interface Table for I/O Multiplexing Engines */
|
|
|
|
|
typedef struct {
|
|
|
|
|
c_err_t (*add)(c_TcpReactor_t* self, c_socket_t sock, uint32_t events);
|
|
|
|
|
c_err_t (*remove)(c_TcpReactor_t* self, c_socket_t sock);
|
|
|
|
|
c_err_t (*poll)(c_TcpReactor_t* self, long timeout_ms, c_TcpServer_t* server, void* args);
|
|
|
|
|
void (*destroy)(c_TcpReactor_t* self);
|
|
|
|
|
} c_TcpReactorVtbl_t;
|
|
|
|
|
|
|
|
|
|
struct c_TcpReactor_t {
|
|
|
|
|
const c_TcpReactorVtbl_t* vtbl;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct c_TcpServer_t {
|
|
|
|
|
c_socket_t listen_sock; /* Master server listening socket descriptor */
|
2026-09-08 12:38:28 +08:00
|
|
|
c_bool_t is_running; /* Server master thread loop state flag */
|
2026-09-08 10:35:16 +08:00
|
|
|
c_TcpReactor_t* reactor; /* Polymorphic multiplexing backend driver link */
|
|
|
|
|
c_TcpServer_OnConnect_t fnOnConnect; /* Connection accept callback hook */
|
|
|
|
|
c_TcpServer_OnRequest_t fnOnRequest; /* Data incoming available callback hook */
|
|
|
|
|
c_TcpServer_OnDisconnect_t fnOnDisconnect; /* Disconnect termination event hook */
|
|
|
|
|
c_TcpServer_OnError_t fnOnError; /* Network operational error event hook */
|
|
|
|
|
c_Allocator_t allocator; /* Deep copy of the user-provided allocator */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
|
|
|
/* */
|
|
|
|
|
|
|
|
|
|
C_STATIC_FORCE_INLINE
|
|
|
|
|
c_err_t c_TcpReactor_Add(c_TcpReactor_t* self, c_socket_t sock, uint32_t events) {
|
|
|
|
|
if (!self || !self->vtbl || !self->vtbl->add || !c_Socket_IsValid(sock)) return C_ERR_PARAM;
|
|
|
|
|
return self->vtbl->add(self, sock, events);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
C_STATIC_FORCE_INLINE
|
|
|
|
|
c_err_t c_TcpReactor_Remove(c_TcpReactor_t* self, c_socket_t sock) {
|
|
|
|
|
if (!self || !self->vtbl || !self->vtbl->remove || !c_Socket_IsValid(sock)) return C_ERR_PARAM;
|
|
|
|
|
return self->vtbl->remove(self, sock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
C_STATIC_FORCE_INLINE
|
|
|
|
|
c_err_t c_TcpReactor_Poll(c_TcpReactor_t* self, long timeout_ms, c_TcpServer_t* server, void* args) {
|
|
|
|
|
if (!self || !self->vtbl || !self->vtbl->poll || !server) return C_ERR_PARAM;
|
|
|
|
|
return self->vtbl->poll(self, timeout_ms, server, args);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
C_STATIC_FORCE_INLINE
|
|
|
|
|
void c_TcpReactor_Destroy(c_TcpReactor_t* self) {
|
|
|
|
|
if (!self || !self->vtbl || !self->vtbl->destroy) return;
|
|
|
|
|
self->vtbl->destroy(self);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
|
|
|
/* */
|
|
|
|
|
|
|
|
|
|
/* Core Lifecycle Primitives */
|
|
|
|
|
c_err_t c_TcpServer_Init(c_TcpServer_t* self, int family, uint16_t port, int backlog, c_Allocator_t* allocator) ;
|
|
|
|
|
void c_TcpServer_Destroy(c_TcpServer_t* self);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Explicitly binds a specific I/O multiplexing reactor back-end driver.
|
|
|
|
|
*/
|
|
|
|
|
c_err_t c_TcpServer_SetReactor(c_TcpServer_t* self, c_TcpReactor_t* reactor);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
C_STATIC_FORCE_INLINE
|
|
|
|
|
c_err_t c_TcpServer_SetCallbacks(c_TcpServer_t* self
|
|
|
|
|
, c_TcpServer_OnConnect_t on_connect
|
|
|
|
|
, c_TcpServer_OnRequest_t on_data
|
|
|
|
|
, c_TcpServer_OnDisconnect_t on_disconnect
|
|
|
|
|
, c_TcpServer_OnError_t on_error)
|
|
|
|
|
{
|
|
|
|
|
if (!self) return C_ERR_PARAM;
|
|
|
|
|
self->fnOnConnect = on_connect;
|
|
|
|
|
self->fnOnRequest = on_data;
|
|
|
|
|
self->fnOnDisconnect = on_disconnect;
|
|
|
|
|
self->fnOnError = on_error;
|
|
|
|
|
return C_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
C_STATIC_FORCE_INLINE
|
|
|
|
|
void c_TcpServer_SetOnConnect(c_TcpServer_t* self, c_TcpServer_OnConnect_t on_connect) {
|
|
|
|
|
if (!self) return;
|
|
|
|
|
self->fnOnConnect = on_connect;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
C_STATIC_FORCE_INLINE
|
|
|
|
|
void c_TcpServer_SetOnData(c_TcpServer_t* self, c_TcpServer_OnRequest_t on_data) {
|
|
|
|
|
if (!self) return;
|
|
|
|
|
self->fnOnRequest = on_data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
C_STATIC_FORCE_INLINE
|
|
|
|
|
void c_TcpServer_SetOnDisconnect(c_TcpServer_t* self, c_TcpServer_OnDisconnect_t on_disconnect) {
|
|
|
|
|
if (!self) return;
|
|
|
|
|
self->fnOnDisconnect = on_disconnect;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
C_STATIC_FORCE_INLINE
|
|
|
|
|
void c_TcpServer_SetOnError(c_TcpServer_t* self, c_TcpServer_OnError_t on_error) {
|
|
|
|
|
if (!self) return;
|
|
|
|
|
self->fnOnError = on_error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Non-recursively runs the multiplexed event polling dispatcher loop layer.
|
|
|
|
|
*/
|
|
|
|
|
c_err_t c_TcpServer_Run(c_TcpServer_t* self, long timeout_ms, void* args);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const char* c_TcpServer_GetErrorString(int code);
|
|
|
|
|
|
|
|
|
|
#endif /*INCLUDED_C_TCPSERVER_H*/
|