#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; }