Skip to content

Instantly share code, notes, and snippets.

@ms747
Created October 24, 2023 10:32
Show Gist options
  • Save ms747/18ab22c90119c704a7800ce8096204fb to your computer and use it in GitHub Desktop.
Save ms747/18ab22c90119c704a7800ce8096204fb to your computer and use it in GitHub Desktop.
Poll Server
#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