Mercurial
view seobeo/main.c @ 0:5695ef413be0
Initialized mono repo with bazels with few examples.
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Tue, 23 Sep 2025 10:05:25 -0700 |
| parents | |
| children | adcfad6e86fb |
line wrap: on
line source
/* ** server.c -- a stream socket server demo */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <arpa/inet.h> #include <sys/wait.h> #include <signal.h> #define PORT "6969" #define BACKLOG 10 // how many pending connections queue will hold 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 *GetInternetaddr(struct sockaddr *sa) { if (sa->sa_family == AF_INET) { return &(((struct sockaddr_in*)sa)->sin_addr); } return &(((struct sockaddr_in6*)sa)->sin6_addr); } int main(void) { int sock_fd, client_fd; struct addrinfo hints, *server_infos, *free_server_info; int yes = 1; // boolean struct sockaddr_storage client_addr; socklen_t sin_size; char client_inet_addr[INET6_ADDRSTRLEN]; struct sigaction sa; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; if (getaddrinfo(NULL, PORT, &hints, &server_infos) == 1) { perror("getaddrinfo"); return 1; } for (free_server_info = server_infos; free_server_info != NULL; free_server_info = free_server_info->ai_next) { if ((sock_fd = socket(free_server_info->ai_family, free_server_info->ai_socktype, free_server_info->ai_protocol)) == -1) { perror("socket"); continue; } if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) { perror("setsockopt"); continue; } if (bind(sock_fd, free_server_info->ai_addr, free_server_info->ai_addrlen) == -1) { close(sock_fd); perror("setsockopt"); continue; } // binded to a open server infos; break; } freeaddrinfo(server_infos); if (free_server_info == NULL) { perror("No free server"); return 1; } if (listen(sock_fd, BACKLOG) != 0) { perror("listen"); return 1; } 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); } printf("server: waiting for connections...\n"); char *response = "HTTP/1.1 OK %s\r\n" "Content-Type: text/txt\r\n" "Content-Length: 13\r\n" "Connection: close\r\n" "\r\n" "Hello, world!"; while (1) { sin_size = sizeof(client_addr); client_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size); if (client_fd == -1) { perror("accept"); continue; } inet_ntop( client_addr.ss_family, GetInternetaddr((struct sockaddr *)&client_addr), client_inet_addr, sizeof client_inet_addr); printf("server: got connection from %s\n", client_inet_addr); // Create a child process if (!fork()) { close(sock_fd); if (send(client_fd, response, strlen(response), 0) == -1) { perror("send"); continue; } close(client_fd); exit(0); } close(client_fd); } return 0; }