## Overview DAP Net Server provides comprehensive server-side infrastructure for creating robust, scalable DAP services and applications. This module implements multi-threaded server architecture, connection management, and request processing capabilities, enabling the development of high-performance server applications within the DAP ecosystem. **Based on:** `dap-sdk/net/server/include/dap_server.h`, `dap-sdk/net/server/src/dap_server.c` ## Document Structure - [[#Overview|Overview]] - [[#Module Structures|Module Structures]] - [[#dap_server_t|dap_server_t - Server Instance]] - [[#dap_server_config_t|dap_server_config_t - Configuration]] - [[#dap_server_client_t|dap_server_client_t - Client Connection]] - [[#dap_server_service_t|dap_server_service_t - Service Registration]] - [[#dap_server_handler_t|dap_server_handler_t - Request Handler]] - [[#Module Functions|Module Functions]] - [[#Server Management|Server Creation and Lifecycle]] - [[#Service Operations|Service Registration and Management]] - [[#Client Management|Connection Handling]] - [[#Request Processing|Request and Response Handling]] - [[#Error Codes|Error Codes]] - [[#Typical Examples|Typical Examples]] ## Module Structures ### dap_server_t Core server instance structure managing all server operations and connections. ```c typedef struct dap_server { struct { char *server_name; // Server identifier name uint16_t port; // Server listening port char *bind_address; // Bind address bool is_running; // Server running status bool is_listening; // Listening status uint32_t active_connections; // Current active connections uint32_t max_connections; // Maximum allowed connections uint64_t total_requests; // Total requests processed dap_time_t startup_time; // Server startup timestamp } pub; struct { dap_events_socket_t *listening_socket; // Main listening socket dap_list_t *client_list; // Connected clients list dap_htable_t *service_table; // Registered services dap_server_config_t *config; // Server configuration dap_worker_pool_t *worker_pool; // Worker thread pool dap_server_callbacks_t *callbacks; // Server event callbacks pthread_mutex_t server_mutex; // Server synchronization dap_server_stats_t *statistics; // Performance statistics bool shutdown_requested; // Graceful shutdown flag dap_ssl_context_t *ssl_context; // SSL/TLS context } priv; } dap_server_t; ``` **Public Fields:** - `server_name` - Unique identifier for the server instance - `port` - Port number the server is listening on - `bind_address` - Network interface address for binding - `is_running` - Server operational status - `is_listening` - Listening socket status - `active_connections` - Current number of active client connections - `max_connections` - Maximum concurrent connections allowed - `total_requests` - Counter of total requests processed ### dap_server_config_t Server configuration structure defining operational parameters. ```c typedef struct dap_server_config { struct { uint32_t max_connections; // Maximum client connections uint32_t worker_threads; // Number of worker threads uint32_t connection_timeout_sec; // Client connection timeout uint32_t request_timeout_sec; // Request processing timeout bool enable_ssl; // SSL/TLS encryption enabled bool enable_compression; // Response compression uint32_t keepalive_timeout_sec; // Keep-alive timeout uint32_t max_request_size; // Maximum request size } pub; struct { uint32_t socket_buffer_size; // Socket buffer size uint32_t thread_stack_size; // Worker thread stack size bool enable_nagle; // Nagle algorithm uint32_t backlog_size; // Listen backlog size bool enable_metrics; // Performance metrics char *ssl_cert_path; // SSL certificate path char *ssl_key_path; // SSL private key path dap_server_security_policy_t security; // Security policies } priv; } dap_server_config_t; ``` ### dap_server_client_t Client connection structure representing connected clients. ```c typedef struct dap_server_client { struct { uint64_t client_id; // Unique client identifier dap_events_socket_t *socket; // Client socket struct sockaddr_storage client_addr; // Client address dap_time_t connected_time; // Connection timestamp dap_time_t last_activity; // Last activity time uint64_t requests_processed; // Requests from this client uint64_t bytes_sent; // Bytes sent to client uint64_t bytes_received; // Bytes received from client dap_client_state_t state; // Client connection state } pub; struct { dap_server_t *server; // Parent server reference dap_buffer_t *request_buffer; // Request buffer dap_buffer_t *response_buffer; // Response buffer dap_client_session_t *session; // Client session data pthread_mutex_t client_mutex; // Client synchronization dap_timer_t *timeout_timer; // Client timeout timer bool is_authenticated; // Authentication status dap_auth_context_t *auth_context; // Authentication context } priv; } dap_server_client_t; ``` ### dap_server_service_t Service registration structure for server endpoints. ```c typedef struct dap_server_service { struct { char *service_name; // Service identifier char *service_path; // URL path or endpoint dap_service_type_t type; // Service type bool is_enabled; // Service enabled status uint64_t requests_handled; // Total requests handled dap_time_t registration_time; // Service registration time uint32_t average_response_time_ms; // Average response time } pub; struct { dap_server_handler_t *handler; // Request handler function void *handler_context; // Handler context data dap_service_middleware_t *middleware; // Middleware chain dap_service_config_t *config; // Service configuration dap_service_stats_t *statistics; // Service statistics pthread_mutex_t service_mutex; // Service synchronization } priv; } dap_server_service_t; ``` ### dap_server_handler_t Request handler structure for processing client requests. ```c typedef struct dap_server_handler { dap_server_handler_callback_t callback; // Handler callback function void *callback_context; // Callback context dap_handler_priority_t priority; // Handler priority char *content_type; // Response content type bool requires_auth; // Authentication required dap_handler_method_t methods; // Supported HTTP methods dap_handler_config_t *config; // Handler configuration } dap_server_handler_t; ``` ## Module Functions ### Server Management #### `dap_server_create()` Creates new server instance with specified configuration. ```c dap_server_t* dap_server_create(const char *a_server_name, const dap_server_config_t *a_config); ``` **Parameters:** - `a_server_name` (const char*) - Unique name for the server instance - `a_config` (const dap_server_config_t*) - Server configuration parameters **Returns:** - `dap_server_t*` - Created server instance - `NULL` - Server creation failed **Error Conditions:** - Returns NULL if a_server_name is NULL or empty - Returns NULL if a_config is NULL or invalid - Returns NULL if memory allocation fails - Returns NULL if socket creation fails **Description:** Creates a new server instance with the specified configuration. The server is created in a stopped state and requires explicit startup. #### `dap_server_destroy()` Destroys server instance and frees all resources. ```c void dap_server_destroy(dap_server_t *a_server); ``` **Parameters:** - `a_server` (dap_server_t*) - Server instance to destroy **Description:** Safely destroys the server by stopping all operations, disconnecting clients, and freeing allocated resources. #### `dap_server_start()` Starts server and begins accepting connections. ```c int dap_server_start(dap_server_t *a_server, const char *a_bind_addr, uint16_t a_port); ``` **Parameters:** - `a_server` (dap_server_t*) - Server instance to start - `a_bind_addr` (const char*) - Address to bind to ("0.0.0.0" for all interfaces) - `a_port` (uint16_t) - Port number to listen on **Returns:** - `0` - Server started successfully - `-1` - Invalid parameters - `-2` - Address binding failed - `-3` - Listen operation failed - `-4` - Worker pool creation failed **Error Conditions:** - Returns -1 if a_server is NULL or a_port is 0 - Returns -2 if bind() system call fails - Returns -3 if listen() system call fails - Returns -4 if worker thread creation fails #### `dap_server_stop()` Stops server gracefully and closes all connections. ```c int dap_server_stop(dap_server_t *a_server); ``` **Parameters:** - `a_server` (dap_server_t*) - Server instance to stop **Returns:** - `0` - Server stopped successfully - `-1` - Invalid server parameter - `-2` - Server not running ### Service Operations #### `dap_server_register_service()` Registers new service endpoint with the server. ```c int dap_server_register_service(dap_server_t *a_server, const char *a_service_name, const char *a_path, dap_server_handler_t *a_handler); ``` **Parameters:** - `a_server` (dap_server_t*) - Server instance - `a_service_name` (const char*) - Service identifier name - `a_path` (const char*) - URL path or endpoint - `a_handler` (dap_server_handler_t*) - Request handler **Returns:** - `0` - Service registered successfully - `-1` - Invalid parameters - `-2` - Service already exists - `-3` - Handler registration failed #### `dap_server_unregister_service()` Unregisters service from the server. ```c int dap_server_unregister_service(dap_server_t *a_server, const char *a_service_name); ``` #### `dap_server_get_service()` Retrieves service by name. ```c dap_server_service_t* dap_server_get_service(dap_server_t *a_server, const char *a_service_name); ``` ### Client Management #### `dap_server_accept_client()` Accepts new client connection. ```c dap_server_client_t* dap_server_accept_client(dap_server_t *a_server, dap_events_socket_t *a_socket); ``` **Parameters:** - `a_server` (dap_server_t*) - Server instance - `a_socket` (dap_events_socket_t*) - Accepted client socket **Returns:** - `dap_server_client_t*` - New client structure - `NULL` - Client acceptance failed #### `dap_server_disconnect_client()` Disconnects client from server. ```c int dap_server_disconnect_client(dap_server_t *a_server, dap_server_client_t *a_client); ``` ### Request Processing #### `dap_server_process_request()` Processes client request through registered handlers. ```c int dap_server_process_request(dap_server_client_t *a_client, const void *a_request, size_t a_request_size); ``` **Parameters:** - `a_client` (dap_server_client_t*) - Client connection - `a_request` (const void*) - Request data - `a_request_size` (size_t) - Size of request data **Returns:** - `0` - Request processed successfully - `-1` - Invalid parameters - `-2` - No handler found - `-3` - Handler execution failed #### `dap_server_send_response()` Sends response to client. ```c int dap_server_send_response(dap_server_client_t *a_client, const void *a_response, size_t a_response_size); ``` ## Error Codes ### Server Error Codes ```c typedef enum dap_server_error { DAP_SERVER_ERROR_SUCCESS = 0, // Operation successful DAP_SERVER_ERROR_INVALID_PARAM = -1, // Invalid parameter provided DAP_SERVER_ERROR_NO_MEMORY = -2, // Memory allocation failed DAP_SERVER_ERROR_SOCKET_FAILED = -3, // Socket operation failed DAP_SERVER_ERROR_BIND_FAILED = -4, // Address binding failed DAP_SERVER_ERROR_LISTEN_FAILED = -5, // Listen operation failed DAP_SERVER_ERROR_ACCEPT_FAILED = -6, // Client accept failed DAP_SERVER_ERROR_SSL_FAILED = -7, // SSL/TLS operation failed DAP_SERVER_ERROR_HANDLER_FAILED = -8, // Request handler failed DAP_SERVER_ERROR_SERVICE_EXISTS = -9, // Service already registered DAP_SERVER_ERROR_SERVICE_NOT_FOUND = -10, // Service not found DAP_SERVER_ERROR_CLIENT_LIMIT = -11, // Client limit reached DAP_SERVER_ERROR_NOT_RUNNING = -12, // Server not running DAP_SERVER_ERROR_ALREADY_RUNNING = -13 // Server already running } dap_server_error_t; ``` ## Typical Examples ### Basic HTTP Server Example ```c #include "dap_common.h" #include "dap_server.h" // HTTP request handler int http_handler(dap_server_client_t *a_client, const void *a_request, size_t a_request_size, void *a_context) { log_it(L_INFO, "Processing HTTP request from client %lu", a_client->pub.client_id); // Simple HTTP response const char *response = "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n" "Content-Length: 48\r\n" "Connection: close\r\n" "\r\n" "<html><body><h1>Hello from DAP Server!</h1></body></html>"; int result = dap_server_send_response(a_client, response, strlen(response)); if (result == 0) { log_it(L_INFO, "✓ HTTP response sent to client %lu", a_client->pub.client_id); } else { log_it(L_ERROR, "✗ Failed to send response: %d", result); } return result; } int example_http_server() { log_it(L_INFO, "=== DAP HTTP Server Example ==="); // Step 1: Create server configuration dap_server_config_t config = { .pub.max_connections = 100, .pub.worker_threads = 4, .pub.connection_timeout_sec = 30, .pub.request_timeout_sec = 60, .pub.enable_ssl = false, .pub.enable_compression = true, .pub.keepalive_timeout_sec = 300, .pub.max_request_size = 1024 * 1024, // 1MB .priv.socket_buffer_size = 8192, .priv.enable_metrics = true, .priv.backlog_size = 128 }; // Step 2: Create server instance dap_server_t *server = dap_server_create("http_server", &config); if (!server) { log_it(L_ERROR, "✗ Failed to create HTTP server"); return -1; } log_it(L_INFO, "✓ HTTP server created successfully"); // Step 3: Register HTTP service dap_server_handler_t handler = { .callback = http_handler, .callback_context = NULL, .priority = DAP_HANDLER_PRIORITY_NORMAL, .content_type = "text/html", .requires_auth = false, .methods = DAP_HANDLER_METHOD_GET | DAP_HANDLER_METHOD_POST }; int result = dap_server_register_service(server, "http_service", "/", &handler); if (result != 0) { log_it(L_ERROR, "✗ Failed to register HTTP service: %d", result); dap_server_destroy(server); return -1; } log_it(L_INFO, "✓ HTTP service registered at path '/'"); // Step 4: Start server result = dap_server_start(server, "0.0.0.0", 8080); if (result != 0) { log_it(L_ERROR, "✗ Failed to start server: %d", result); switch (result) { case -2: log_it(L_ERROR, "Address binding failed - port may be in use"); break; case -3: log_it(L_ERROR, "Listen operation failed"); break; case -4: log_it(L_ERROR, "Worker pool creation failed"); break; } dap_server_destroy(server); return -1; } log_it(L_INFO, "✓ HTTP server started on 0.0.0.0:8080"); log_it(L_INFO, "Server ready to accept connections..."); // Step 5: Let server run (in real application, this would be event-driven) log_it(L_INFO, "Server running for 30 seconds..."); sleep(30); // Step 6: Display server statistics log_it(L_INFO, "Server Statistics:"); log_it(L_INFO, " Active connections: %u", server->pub.active_connections); log_it(L_INFO, " Total requests: %lu", server->pub.total_requests); log_it(L_INFO, " Uptime: %lu seconds", dap_time_now() - server->pub.startup_time); // Step 7: Graceful shutdown log_it(L_INFO, "Shutting down server..."); result = dap_server_stop(server); if (result == 0) { log_it(L_INFO, "✓ Server stopped gracefully"); } else { log_it(L_ERROR, "✗ Server stop failed: %d", result); } // Step 8: Cleanup dap_server_destroy(server); log_it(L_INFO, "✓ HTTP Server example completed"); return 0; } ``` ### Multi-Service Server Example ```c #include "dap_common.h" #include "dap_server.h" // API endpoint handler int api_handler(dap_server_client_t *a_client, const void *a_request, size_t a_request_size, void *a_context) { log_it(L_INFO, "Processing API request from client %lu", a_client->pub.client_id); const char *json_response = "HTTP/1.1 200 OK\r\n" "Content-Type: application/json\r\n" "Content-Length: 54\r\n" "\r\n" "{\"status\":\"success\",\"message\":\"DAP API is running\"}"; return dap_server_send_response(a_client, json_response, strlen(json_response)); } // Status endpoint handler int status_handler(dap_server_client_t *a_client, const void *a_request, size_t a_request_size, void *a_context) { dap_server_t *server = (dap_server_t*)a_context; char status_response[512]; snprintf(status_response, sizeof(status_response), "HTTP/1.1 200 OK\r\n" "Content-Type: application/json\r\n" "Content-Length: %d\r\n" "\r\n" "{\"server\":\"%s\",\"connections\":%u,\"requests\":%lu,\"uptime\":%lu}", 0, // Will be calculated server->pub.server_name, server->pub.active_connections, server->pub.total_requests, dap_time_now() - server->pub.startup_time); // Update content length char *content_start = strstr(status_response, "\r\n\r\n") + 4; size_t content_length = strlen(content_start); snprintf(status_response, sizeof(status_response), "HTTP/1.1 200 OK\r\n" "Content-Type: application/json\r\n" "Content-Length: %zu\r\n" "\r\n" "{\"server\":\"%s\",\"connections\":%u,\"requests\":%lu,\"uptime\":%lu}", content_length, server->pub.server_name, server->pub.active_connections, server->pub.total_requests, dap_time_now() - server->pub.startup_time); return dap_server_send_response(a_client, status_response, strlen(status_response)); } int example_multi_service_server() { log_it(L_INFO, "=== Multi-Service Server Example ==="); // Step 1: Create server with enhanced configuration dap_server_config_t config = { .pub.max_connections = 200, .pub.worker_threads = 8, .pub.connection_timeout_sec = 60, .pub.request_timeout_sec = 30, .pub.enable_compression = true, .priv.enable_metrics = true }; dap_server_t *server = dap_server_create("multi_service_server", &config); if (!server) { log_it(L_ERROR, "✗ Failed to create server"); return -1; } // Step 2: Register API service dap_server_handler_t api_handler_struct = { .callback = api_handler, .callback_context = server, .priority = DAP_HANDLER_PRIORITY_HIGH, .content_type = "application/json", .requires_auth = false, .methods = DAP_HANDLER_METHOD_GET | DAP_HANDLER_METHOD_POST }; if (dap_server_register_service(server, "api_service", "/api", &api_handler_struct) != 0) { log_it(L_ERROR, "✗ Failed to register API service"); goto cleanup; } log_it(L_INFO, "✓ API service registered at '/api'"); // Step 3: Register status service dap_server_handler_t status_handler_struct = { .callback = status_handler, .callback_context = server, .priority = DAP_HANDLER_PRIORITY_NORMAL, .content_type = "application/json", .requires_auth = false, .methods = DAP_HANDLER_METHOD_GET }; if (dap_server_register_service(server, "status_service", "/status", &status_handler_struct) != 0) { log_it(L_ERROR, "✗ Failed to register status service"); goto cleanup; } log_it(L_INFO, "✓ Status service registered at '/status'"); // Step 4: Start server if (dap_server_start(server, "127.0.0.1", 9090) != 0) { log_it(L_ERROR, "✗ Failed to start server"); goto cleanup; } log_it(L_INFO, "✓ Multi-service server started on 127.0.0.1:9090"); // Step 5: Display registered services log_it(L_INFO, "Registered Services:"); dap_server_service_t *api_service = dap_server_get_service(server, "api_service"); if (api_service) { log_it(L_INFO, " API Service: %s (enabled: %s)", api_service->pub.service_path, api_service->pub.is_enabled ? "yes" : "no"); } dap_server_service_t *status_service = dap_server_get_service(server, "status_service"); if (status_service) { log_it(L_INFO, " Status Service: %s (enabled: %s)", status_service->pub.service_path, status_service->pub.is_enabled ? "yes" : "no"); } // Step 6: Run server log_it(L_INFO, "Server running - try accessing:"); log_it(L_INFO, " http://127.0.0.1:9090/api"); log_it(L_INFO, " http://127.0.0.1:9090/status"); sleep(60); cleanup: dap_server_stop(server); dap_server_destroy(server); log_it(L_INFO, "✓ Multi-Service Server example completed"); return 0; } ``` --- **See also:** [[Module DAP Net - Client|Module DAP Net - Client]], [[Module DAP Net - Stream|Module DAP Net - Stream]], [[Module DAP IO|Module DAP IO]] --- *Based on: `dap-sdk/net/server/include/dap_server.h`, `dap-sdk/net/server/src/dap_server.c`*