Mercurial
view seobeo/main.c @ 3:2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Wed, 24 Sep 2025 18:49:09 -0700 |
| parents | adcfad6e86fb |
| children | 0b3b4f5887bb |
line wrap: on
line source
/* ** server.c -- a stream socket server demo */ #include "seobeo/seobeo.h" Dowa_PHashMap cache; void SigchildHandler(int s) { (void)s; // quiet unused variable warning // waitpid() might overwrite errno, so we save and restore it: int saved_errno = errno; while(waitpid(-1, NULL, WNOHANG) > 0); errno = saved_errno; } void HandleClientRequest(int client_fd) { size_t idx = Dowa_HashMap_GetPosition(cache, "index.html"); Dowa_PHashEntry entry = cache->entries[idx]; if (!entry) { // 404 response if missing const char *not_found = "HTTP/1.1 404 Not Found\r\n" "Content-Length: 0\r\n" "Connection: close\r\n" "\r\n"; send(client_fd, not_found, strlen(not_found), 0); close(client_fd); return; } // 3) Prepare header with the correct contentālength size_t body_size = entry->capacity; const char *template = "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n" "Content-Length: %zu\r\n" "Connection: close\r\n" "\r\n"; // Compute how large the header is and allocate just enough space int header_len = snprintf(NULL, 0, template, body_size); char *header = malloc(header_len + 1); if (!header) { perror("malloc"); close(client_fd); return; } snprintf(header, header_len + 1, template, body_size); // 4) Send header send(client_fd, header, header_len, 0); free(header); // 5) Stream the body in a loop until everything is sent ssize_t total_sent = 0; const char *body = entry->buffer; while ((size_t)total_sent < body_size) { ssize_t sent = send( client_fd, body + total_sent, body_size - total_sent, 0 ); if (sent <= 0) { // error or connection closed by client break; } total_sent += sent; } // 6) Tear down close(client_fd); } int main(void) { cache = Dowa_HashMap_Create(1024); if (Dowa_Cache_Folder(cache, "seobeo/pages") != 0) { perror("Dowa_Cache_Folder"); return -1; } struct sigaction sa; sa.sa_handler = SigchildHandler; // reap all dead processes sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1); } int sock_fd = Seobeo_CreateSocket(1, "6969", 10); Seobeo_ListenClient(sock_fd, &HandleClientRequest); return 0; }