Created
October 24, 2023 10:32
-
-
Save ms747/18ab22c90119c704a7800ce8096204fb to your computer and use it in GitHub Desktop.
Poll Server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <netinet/in.h> | |
#include <sys/socket.h> | |
#include <sys/epoll.h> | |
#define PORT 8080 | |
#define MAX_EVENTS 256 | |
#define HELLO_RESPONSE "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 14\r\n\r\nHello, World!\n" | |
int set_nonblocking(int fd) { | |
int flags = fcntl(fd, F_GETFL, 0); | |
if (flags == -1) { | |
perror("Error in fcntl F_GETFL"); | |
return 1; | |
} | |
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { | |
perror("Error in fcntl F_SETFL"); | |
return 1; | |
} | |
return 0; | |
} | |
int main() { | |
int server_socket = socket(AF_INET, SOCK_STREAM, 0); | |
if (server_socket == -1) { | |
perror("socket"); | |
return 1; | |
} | |
int enable_reuse = 1; | |
if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &enable_reuse, sizeof(int)) == -1) { | |
perror("Error in setsockopt"); | |
return 1; | |
} | |
if (set_nonblocking(server_socket)) { | |
perror("Error in set_nonblocking"); | |
return 1; | |
} | |
struct sockaddr_in server_addr; | |
server_addr.sin_family = AF_INET; | |
server_addr.sin_addr.s_addr = INADDR_ANY; | |
server_addr.sin_port = htons(PORT); | |
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { | |
perror("bind"); | |
return 1; | |
} | |
if (listen(server_socket, MAX_EVENTS) == -1) { | |
perror("listen"); | |
return 1; | |
} | |
printf("Server is listening on port %d...\n", PORT); | |
int epoll_fd = epoll_create1(0); | |
if (epoll_fd == -1) { | |
perror("Error in epoll_create1"); | |
return 1; | |
} | |
struct epoll_event event; | |
event.events = EPOLLIN | EPOLLET; | |
event.data.fd = server_socket; | |
struct epoll_event epoll_events[MAX_EVENTS]; | |
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_socket, &event) == -1) { | |
perror("Error in epoll_ctl"); | |
return 1; | |
} | |
char* buffer = malloc(sizeof(char) * 256); | |
while (1) { | |
int events = epoll_wait(epoll_fd, epoll_events, MAX_EVENTS, -1); | |
for (int i = 0; i < events; i++) { | |
if (epoll_events[i].data.fd == server_socket) { | |
int client_socket = accept(server_socket, NULL, NULL); | |
if (client_socket == -1) { | |
perror("Error in accept"); | |
return 1; | |
} else { | |
if (set_nonblocking(client_socket)) { | |
perror("Error in set_nonblocking"); | |
return 1; | |
} | |
event.data.fd = client_socket; | |
event.events = EPOLLIN | EPOLLET; | |
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_socket, &event) == -1) { | |
perror("Error in epoll_ctl"); | |
return 1; | |
} | |
} | |
} else { | |
int client_socket = epoll_events[i].data.fd; | |
int bytes_received = recv(client_socket, buffer, 256, 0); | |
if (bytes_received <= 0) { | |
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_socket, NULL); | |
close(client_socket); | |
} else { | |
sendto(client_socket, HELLO_RESPONSE, sizeof(HELLO_RESPONSE), 0, NULL, 0); | |
} | |
} | |
} | |
} | |
free(buffer); | |
close(server_socket); | |
close(epoll_fd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment