Created
May 1, 2025 15:36
-
-
Save nazibul7/002b2a93b425a2e1c19c77cd9b19675a to your computer and use it in GitHub Desktop.
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 <string.h> | |
#include <arpa/inet.h> | |
#include <sys/epoll.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <errno.h> | |
#define MAX_EVENTS 100 | |
#define PORT 4000 | |
#define BUFFER_SIZE 1024 | |
void set_nonblocking(int fd) | |
{ | |
int flags = fcntl(fd, F_GETFL, 0); | |
if (flags == -1) | |
{ | |
perror("fcntl F_GETFL"); | |
return; | |
} | |
int updatedFlags = fcntl(fd, F_SETFL, flags | O_NONBLOCK); | |
if (updatedFlags == -1) | |
{ | |
perror("fcntl F_SETFL O_NONBLOCK"); | |
} | |
} | |
int main() | |
{ | |
int server_id, client_id; | |
struct sockaddr_in address; | |
int addlen = sizeof(address); | |
server_id = socket(AF_INET, SOCK_STREAM, 0); | |
if (server_id < 0) | |
{ | |
perror("Socket creation failed"); | |
exit(EXIT_FAILURE); | |
} | |
memset(&address, 0, addlen); | |
address.sin_family = AF_INET; | |
address.sin_addr.s_addr = INADDR_ANY; | |
address.sin_port = htons(PORT); | |
if (bind(server_id, (struct sockaddr *)&address, addlen) < 0) | |
{ | |
perror("Failed to bind"); | |
close(server_id); | |
exit(EXIT_FAILURE); | |
} | |
if (listen(server_id, 128) < 0) | |
{ | |
perror("Listen failed"); | |
close(server_id); | |
exit(EXIT_FAILURE); | |
} | |
printf("Server is listening on PORT %d\n", PORT); | |
int epoll_fd = epoll_create1(0); | |
if (epoll_fd == -1) | |
{ | |
perror("epoll_create1 failed"); | |
close(server_id); | |
exit(EXIT_FAILURE); | |
} | |
struct epoll_event event, events[MAX_EVENTS]; | |
event.events = EPOLLIN; | |
event.data.fd = server_id; | |
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_id, &event) == -1) | |
{ | |
perror("epoll_ctl failed"); | |
close(server_id); | |
exit(EXIT_FAILURE); | |
} | |
while (1) | |
{ | |
int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1); | |
if (nfds == -1) | |
{ | |
perror("epoll_wait failed"); | |
break; | |
} | |
for (int i = 0; i < nfds; i++) | |
{ | |
if (events[i].data.fd == server_id) | |
{ | |
client_id = accept(server_id, (struct sockaddr *)&address, (socklen_t *)&addlen); | |
if (client_id == -1) | |
{ | |
perror("accept failed"); | |
continue; | |
} | |
set_nonblocking(client_id); | |
event.events = EPOLLIN | EPOLLET; | |
event.data.fd = client_id; | |
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_id, &event) == -1) | |
{ | |
perror("epoll_ctl for client failed"); | |
close(client_id); | |
continue; | |
} | |
printf("Accepted new connection from client: %d\n", client_id); | |
} | |
else | |
{ | |
while (1) | |
{ | |
char buffer[BUFFER_SIZE]; | |
ssize_t bytes_read = read(events[i].data.fd, buffer, sizeof(buffer) - 1); | |
if (bytes_read == 0) | |
{ | |
printf("Client closed connection: %d\n", events[i].data.fd); | |
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, events[i].data.fd, NULL); | |
close(events[i].data.fd); | |
break; | |
} | |
else if (bytes_read > 0) | |
{ | |
buffer[bytes_read] = '\0'; // Null-terminate the buffer | |
printf("Received request: %s\n", buffer); | |
if (strncmp(buffer, "GET", 3) == 0 || strncmp(buffer, "POST", 4) == 0) | |
{ | |
char http_response[] = | |
"HTTP/1.1 200 OK\r\n" | |
"Content-Type: text/html\r\n" | |
"Connection: close\r\n" | |
"Content-Length: 31\r\n" | |
"\r\n" | |
"<html><body>hello</body></html>"; | |
write(events[i].data.fd, http_response, strlen(http_response)); | |
printf("Sent HTTP response to client: %d\n", events[i].data.fd); | |
close(events[i].data.fd); | |
break; | |
} | |
else | |
{ | |
write(events[i].data.fd, buffer, bytes_read); | |
printf("Echoed data back to client: %d\n", events[i].data.fd); | |
close(events[i].data.fd); | |
break; | |
} | |
} | |
else if (bytes_read == -1) | |
{ | |
if (errno != EAGAIN && errno != EWOULDBLOCK) | |
{ | |
break; | |
} | |
else | |
{ | |
perror("read error"); | |
close(events[i].data.fd); | |
break; | |
} | |
} | |
} | |
} | |
} | |
} | |
close(server_id); | |
close(epoll_fd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment