Files

162 lines
5.9 KiB
C
Raw Permalink Normal View History

2026-09-08 12:38:28 +08:00
#ifndef INCLUDED_C_TCPCLIENT_H
#define INCLUDED_C_TCPCLIENT_H
#ifndef INCLUDED_C_SOCKET_H
#include <c_Socket.h>
#endif /*INCLUDED_C_SOCKET_H*/
#ifndef INCLUDED_C_ALLOCATOR_H
#include <c_Allocator.h>
#endif /*INCLUDED_C_ALLOCATOR_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
#define C_TCPCLIENT_ERR_ON_POLL 1001
#define C_TCPCLIENT_ERR_ON_ACCEPT 1002
#define C_TCPCLIENT_ERR_ON_POLLERR 1003
#define C_TCPCLIENT_ERR_ON_RECV 1004
#define C_TCPCLIENT_ERR_ON_CONNECT 1005
#define C_TCPCLIENT_INITIALIZE {0}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
typedef struct c_TcpClient_t c_TcpClient_t;
typedef bool (*c_TcpClient_OnConnect_t)(c_TcpClient_t* client, void* args);
typedef bool (*c_TcpClient_OnData_t)(c_TcpClient_t* client, void* args);
typedef void (*c_TcpClient_OnDisconnect_t)(c_TcpClient_t* client, void* args);
typedef void (*c_TcpClient_OnError_t)(c_TcpClient_t* client, c_err_t error_code, void* args);
typedef struct c_TcpClientReactor_t c_TcpClientReactor_t;
typedef struct {
c_err_t (*add)(c_TcpClientReactor_t* self, c_socket_t sock, uint32_t events);
c_err_t (*remove)(c_TcpClientReactor_t* self, c_socket_t sock);
c_err_t (*poll)(c_TcpClientReactor_t* self, long timeout_ms, c_TcpClient_t* client, void* args);
void (*destroy)(c_TcpClientReactor_t* self);
} c_TcpClientReactorVtbl_t;
struct c_TcpClientReactor_t {
const c_TcpClientReactorVtbl_t* vtbl;
};
struct c_TcpClient_t {
c_socket_t sock;
c_bool_t is_linked;
c_TcpClientReactor_t* reactor;
c_TcpClient_OnConnect_t fnOnConnect;
c_TcpClient_OnData_t fnOnData;
c_TcpClient_OnDisconnect_t fnOnDisconnect;
c_TcpClient_OnError_t fnOnError;
c_Allocator_t allocator;
};
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
C_STATIC_FORCE_INLINE
c_err_t c_TcpClientReactor_Add(c_TcpClientReactor_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_TcpClientReactor_Remove(c_TcpClientReactor_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_TcpClientReactor_Poll(c_TcpClientReactor_t* self, long timeout_ms, c_TcpClient_t* client, void* args) {
if (!self || !self->vtbl || !self->vtbl->poll || !client) return C_ERR_PARAM;
return self->vtbl->poll(self, timeout_ms, client, args);
}
C_STATIC_FORCE_INLINE
void c_TcpClientReactor_Destroy(c_TcpClientReactor_t* self) {
if (!self || !self->vtbl || !self->vtbl->destroy) return;
self->vtbl->destroy(self);
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
/**
* @brief Establishes a synchronous stream connection to a remote server host.
* @param family Address family (e.g., AF_INET, AF_INET6, or AF_UNSPEC)
* @param server Host destination string (e.g., "127.0.0.1" or "domain.com")
* @param port Service port string identifier (e.g., "8080")
* @param args User defined arguments
* @param allocator Explicit allocator context used to configure socket instances
*/
c_err_t c_TcpClient_Connect(c_TcpClient_t* self, int family, const char* server, const char* port,
void* args,
c_Allocator_t* allocator);
/**
* @brief Sends a raw data block across the socket, looping until the full buffer is dispatched.
* @param buffer Pointer to the source data block payload to transmit.
* @param bytes_to_send Exact size threshold of the payload block in bytes.
* @param out_bytes_sent Receives the actual number of bytes written out to the wire.
*/
c_err_t c_TcpClient_Send(c_TcpClient_t* self, const void* buffer, c_size_t bytes_to_send, c_size_t* out_bytes_sent);
/**
* @brief Reads a data block up to the requested size from the socket channel.
* @param buffer Pointer to the destination buffer to hold incoming data.
* @param max_bytes_to_read Upper ceiling threshold size of bytes to pull.
* @param out_bytes_read Receives the actual number of bytes fetched from the wire.
*/
c_err_t c_TcpClient_Recv(c_TcpClient_t* self, void* buffer, c_size_t max_bytes_to_read, c_size_t* out_bytes_read);
/**
* @brief Safely shuts down pipelines, closes active sockets, and recycles memory.
*/
void c_TcpClient_Destroy(c_TcpClient_t* self);
/**
* @brief Executes a non-recursive, single-pass asynchronous polling event dispatch iteration for the client.
*/
c_err_t c_TcpClient_PollEvents(c_TcpClient_t* self, long timeout_ms, void* args);
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
C_STATIC_FORCE_INLINE
void c_TcpClient_SetReactor(c_TcpClient_t* self, c_TcpClientReactor_t* reactor) {
if (!self || !reactor) return;
self->reactor = reactor;
}
C_STATIC_FORCE_INLINE
void c_TcpClient_SetOnConnect(c_TcpClient_t* self, c_TcpClient_OnConnect_t fnOnConnect) {
if (!self ) return;
self->fnOnConnect = fnOnConnect;
}
C_STATIC_FORCE_INLINE
void c_TcpClient_SetOnData(c_TcpClient_t* self, c_TcpClient_OnData_t fnOnData) {
if (!self ) return;
self->fnOnData = fnOnData;
}
C_STATIC_FORCE_INLINE
void c_TcpClient_SetOnDisconnect(c_TcpClient_t* self, c_TcpClient_OnDisconnect_t fnOnDisconnect) {
if (!self ) return;
self->fnOnDisconnect = fnOnDisconnect;
}
C_STATIC_FORCE_INLINE
void c_TcpClient_SetOnError(c_TcpClient_t* self, c_TcpClient_OnError_t fnOnError) {
if (!self ) return;
self->fnOnError = fnOnError;
}
#endif /*INCLUDED_C_TCPCLIENT_H*/