Files
cKit/Foundation/c_TcpPollReactor.t.c
T
2026-09-08 10:35:16 +08:00

102 lines
3.3 KiB
C

#include "c_TcpPollReactor.h"
#include "c_Test.h"
#include "c_TcpServer.h"
static int g_tracking_counter = 0;
static bool OnConnectHandler(c_socket_t s, const c_SockAddr_t* addr, void* args) {
(void)addr; (void)args;
g_tracking_counter = 10;
char ip_buffer[NI_MAXHOST];
char port_buffer[NI_MAXSERV];
// 3. 将二进制地址转换为明文的 IP 和 端口字符串
// NI_NUMERICHOST: 以数字形式返回 IP
// NI_NUMERICSERV: 以数字形式返回端口号(而不是服务名如 http/ftp)
c_err_t err = c_SocketUtil_GetNameInfoForSocket(s, ip_buffer, NI_MAXHOST, port_buffer, NI_MAXSERV);
if (err == 0) {
printf("Connect from IP:PORT %s:%s\n", ip_buffer, port_buffer);
}
return true;
}
static bool OnDataHandler(c_socket_t s, void* args) {
(void)s; (void)args;
char ip_buffer[NI_MAXHOST];
char port_buffer[NI_MAXSERV];
// 3. 将二进制地址转换为明文的 IP 和 端口字符串
// NI_NUMERICHOST: 以数字形式返回 IP
// NI_NUMERICSERV: 以数字形式返回端口号(而不是服务名如 http/ftp)
c_err_t err = c_SocketUtil_GetNameInfoForSocket(s, ip_buffer, NI_MAXHOST, port_buffer, NI_MAXSERV);
if (err == 0) {
printf("Receive data from IP:PORT %s:%s\n", ip_buffer, port_buffer);
}
return false; /* Instantly signal termination to verify disconnect loops */
}
/* Disconnect handler callback matching your exact specification naming format */
static void OnDisconnectHandler(c_socket_t s, void* args) {
(void)s; (void)args;
g_tracking_counter = 0; /* Clear metrics register */
char ip_buffer[NI_MAXHOST];
char port_buffer[NI_MAXSERV];
// 3. 将二进制地址转换为明文的 IP 和 端口字符串
// NI_NUMERICHOST: 以数字形式返回 IP
// NI_NUMERICSERV: 以数字形式返回端口号(而不是服务名如 http/ftp)
c_err_t err = c_SocketUtil_GetNameInfoForSocket(s, ip_buffer, NI_MAXHOST, port_buffer, NI_MAXSERV);
if (err == 0) {
printf("Client Closed IP:PORT %s:%s\n", ip_buffer, port_buffer);
} else {
fprintf(stderr, "getnameinfo 失败: %s\n", gai_strerror(c_Socket_GetErrno()));
}
}
TEST_CASE(test_multiplex_reactor_server_polling) {
c_Socket_Init();
c_TcpServer_t server;
c_err_t err = c_TcpServer_Init(&server, AF_INET, 8888, 512, NULL);
ASSERT_INT_EQ(C_SUCCESS, err);
/* Hook callbacks using the realigned layout names */
c_TcpServer_SetCallbacks(&server, OnConnectHandler, OnDataHandler, OnDisconnectHandler);
/* 1. Instantiate the poll driver subclass instance */
c_TcpReactor_t* poll_backend = NULL;
err = c_TcpPollReactor_Create(&poll_backend, &server.allocator);
ASSERT_INT_EQ(C_SUCCESS, err);
/* 2. Bind the engine onto the polymorphic execution loop layer */
err = c_TcpServer_SetReactor(&server, poll_backend);
ASSERT_INT_EQ(C_SUCCESS, err);
/* 3. Execute a non-blocking test loop pass with a quick 50ms timeout threshold */
while (server.is_running) {
err = c_TcpServer_Run(&server, 60000, NULL);
ASSERT_INT_EQ(C_SUCCESS, err);
}
c_TcpServer_Destroy(&server);
c_Socket_Destroy();
}
int main(void) {
TEST_START(TcpServer_MultiplexReactor_Suite);
RUN_TEST(test_multiplex_reactor_server_polling);
TEST_REPORT();
RETURN_TEST_STATUS;
}