Mercurial
comparison seobeo/main.c @ 1:adcfad6e86fb
Updated naming and separated out some logic within seobeo.
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Wed, 24 Sep 2025 09:11:20 -0700 |
| parents | 5695ef413be0 |
| children | 2758f5527d2b |
comparison
equal
deleted
inserted
replaced
| 0:5695ef413be0 | 1:adcfad6e86fb |
|---|---|
| 1 /* | 1 /* |
| 2 ** server.c -- a stream socket server demo | 2 ** server.c -- a stream socket server demo |
| 3 */ | 3 */ |
| 4 | 4 |
| 5 #include <stdio.h> | 5 #include "seobeo/seobeo.h" |
| 6 #include <stdlib.h> | |
| 7 #include <unistd.h> | |
| 8 #include <errno.h> | |
| 9 #include <string.h> | |
| 10 #include <sys/types.h> | |
| 11 #include <sys/socket.h> | |
| 12 #include <netinet/in.h> | |
| 13 #include <netdb.h> | |
| 14 #include <arpa/inet.h> | |
| 15 #include <sys/wait.h> | |
| 16 #include <signal.h> | |
| 17 | |
| 18 #define PORT "6969" | |
| 19 | |
| 20 #define BACKLOG 10 // how many pending connections queue will hold | |
| 21 | 6 |
| 22 void SigchildHandler(int s) | 7 void SigchildHandler(int s) |
| 23 { | 8 { |
| 24 (void)s; // quiet unused variable warning | 9 (void)s; // quiet unused variable warning |
| 25 | 10 |
| 40 } | 25 } |
| 41 | 26 |
| 42 return &(((struct sockaddr_in6*)sa)->sin6_addr); | 27 return &(((struct sockaddr_in6*)sa)->sin6_addr); |
| 43 } | 28 } |
| 44 | 29 |
| 30 void HandleClientRequest(int client_fd) | |
| 31 { | |
| 32 FILE *file = fopen("seobeo/index.html", "rb"); | |
| 33 if (!file) { | |
| 34 perror("fopen"); | |
| 35 return; | |
| 36 } | |
| 37 | |
| 38 fseek(file, 0, SEEK_END); | |
| 39 size_t size = ftell(file); | |
| 40 fseek(file, 0, SEEK_SET); | |
| 41 | |
| 42 char *data = malloc(size); | |
| 43 fread(data, 1, size, file); | |
| 44 fclose(file); | |
| 45 | |
| 46 char *header = malloc(100); | |
| 47 sprintf( | |
| 48 header, | |
| 49 "HTTP/1.1 200 OK\r\n" | |
| 50 "Content-Type: text/html\r\n" | |
| 51 "Content-Length: %zu\r\n" | |
| 52 "Connection: close\r\n" | |
| 53 "\r\n", | |
| 54 size | |
| 55 ); | |
| 56 | |
| 57 send(client_fd, header, strlen(header), 0); | |
| 58 ssize_t total_sent = 0; | |
| 59 while (total_sent < size) | |
| 60 { | |
| 61 ssize_t sent = send(client_fd, data + total_sent, size - total_sent, 0); | |
| 62 if (sent <= 0) break; | |
| 63 total_sent += sent; | |
| 64 } | |
| 65 | |
| 66 close(client_fd); | |
| 67 } | |
| 68 | |
| 45 int main(void) | 69 int main(void) |
| 46 { | 70 { |
| 47 int sock_fd, client_fd; | 71 int32 client_fd; |
| 48 struct addrinfo hints, *server_infos, *free_server_info; | |
| 49 int yes = 1; // boolean | |
| 50 | |
| 51 struct sockaddr_storage client_addr; | 72 struct sockaddr_storage client_addr; |
| 52 socklen_t sin_size; | 73 socklen_t sin_size; |
| 53 | 74 |
| 54 char client_inet_addr[INET6_ADDRSTRLEN]; | 75 char client_inet_addr[INET6_ADDRSTRLEN]; |
| 55 | 76 |
| 56 struct sigaction sa; | 77 struct sigaction sa; |
| 57 | |
| 58 memset(&hints, 0, sizeof(hints)); | |
| 59 hints.ai_family = AF_INET; | |
| 60 hints.ai_socktype = SOCK_STREAM; | |
| 61 hints.ai_flags = AI_PASSIVE; | |
| 62 | |
| 63 if (getaddrinfo(NULL, PORT, &hints, &server_infos) == 1) | |
| 64 { | |
| 65 perror("getaddrinfo"); | |
| 66 return 1; | |
| 67 } | |
| 68 | |
| 69 for (free_server_info = server_infos; free_server_info != NULL; free_server_info = free_server_info->ai_next) | |
| 70 { | |
| 71 if ((sock_fd = socket(free_server_info->ai_family, free_server_info->ai_socktype, free_server_info->ai_protocol)) == -1) | |
| 72 { | |
| 73 perror("socket"); | |
| 74 continue; | |
| 75 } | |
| 76 | |
| 77 if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) | |
| 78 { | |
| 79 perror("setsockopt"); | |
| 80 continue; | |
| 81 } | |
| 82 | |
| 83 if (bind(sock_fd, free_server_info->ai_addr, free_server_info->ai_addrlen) == -1) | |
| 84 { | |
| 85 close(sock_fd); | |
| 86 perror("setsockopt"); | |
| 87 continue; | |
| 88 } | |
| 89 | |
| 90 // binded to a open server infos; | |
| 91 break; | |
| 92 } | |
| 93 | |
| 94 freeaddrinfo(server_infos); | |
| 95 | |
| 96 if (free_server_info == NULL) | |
| 97 { | |
| 98 perror("No free server"); | |
| 99 return 1; | |
| 100 } | |
| 101 | |
| 102 if (listen(sock_fd, BACKLOG) != 0) | |
| 103 { | |
| 104 perror("listen"); | |
| 105 return 1; | |
| 106 } | |
| 107 | 78 |
| 108 sa.sa_handler = SigchildHandler; // reap all dead processes | 79 sa.sa_handler = SigchildHandler; // reap all dead processes |
| 109 sigemptyset(&sa.sa_mask); | 80 sigemptyset(&sa.sa_mask); |
| 110 sa.sa_flags = SA_RESTART; | 81 sa.sa_flags = SA_RESTART; |
| 111 if (sigaction(SIGCHLD, &sa, NULL) == -1) { | 82 if (sigaction(SIGCHLD, &sa, NULL) == -1) { |
| 112 perror("sigaction"); | 83 perror("sigaction"); |
| 113 exit(1); | 84 exit(1); |
| 114 } | 85 } |
| 115 | 86 |
| 87 int sock_fd = Seobeo_CreateSocket(1, "6969", 10); | |
| 88 | |
| 116 printf("server: waiting for connections...\n"); | 89 printf("server: waiting for connections...\n"); |
| 117 | |
| 118 char *response = | |
| 119 "HTTP/1.1 OK %s\r\n" | |
| 120 "Content-Type: text/txt\r\n" | |
| 121 "Content-Length: 13\r\n" | |
| 122 "Connection: close\r\n" | |
| 123 "\r\n" | |
| 124 "Hello, world!"; | |
| 125 | 90 |
| 126 while (1) | 91 while (1) |
| 127 { | 92 { |
| 128 sin_size = sizeof(client_addr); | 93 sin_size = sizeof(client_addr); |
| 129 client_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size); | 94 client_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size); |
| 130 | 95 |
| 131 if (client_fd == -1) | 96 if (client_fd == -1) |
| 132 { | 97 { |
| 133 perror("accept"); | 98 perror("accept"); |
| 134 continue; | 99 break; |
| 135 } | 100 } |
| 136 | 101 |
| 137 inet_ntop( | 102 inet_ntop( |
| 138 client_addr.ss_family, | 103 client_addr.ss_family, |
| 139 GetInternetaddr((struct sockaddr *)&client_addr), | 104 GetInternetaddr((struct sockaddr *)&client_addr), |
| 143 | 108 |
| 144 // Create a child process | 109 // Create a child process |
| 145 if (!fork()) | 110 if (!fork()) |
| 146 { | 111 { |
| 147 close(sock_fd); | 112 close(sock_fd); |
| 148 if (send(client_fd, response, strlen(response), 0) == -1) | 113 HandleClientRequest(client_fd); |
| 149 { | |
| 150 perror("send"); | |
| 151 continue; | |
| 152 } | |
| 153 close(client_fd); | |
| 154 exit(0); | 114 exit(0); |
| 155 } | 115 } |
| 156 | 116 |
| 157 close(client_fd); | 117 close(client_fd); |
| 158 } | 118 } |