C语言 epoll 轮询 HTTP 服务器示例
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/epoll.h> #include <sys/socket.h>
#define MAX_EVENTS 10 #define BUFFER_SIZE 1024
void handle_request(int client_fd) { char buffer[BUFFER_SIZE]; memset(buffer, 0, BUFFER_SIZE);
// 读取客户端请求
ssize_t bytes_read = read(client_fd, buffer, BUFFER_SIZE - 1);
if (bytes_read <= 0) {
printf("Error reading request.
"); close(client_fd); return; }
// 处理请求并构造响应
char response[BUFFER_SIZE];
sprintf(response, "HTTP/1.1 200 OK\nContent-Length: 12\n\nHello World!");
// 发送响应给客户端
ssize_t bytes_written = write(client_fd, response, strlen(response));
if (bytes_written <= 0) {
printf("Error writing response.
"); }
// 关闭客户端连接
close(client_fd);
}
int main() { int server_fd, epoll_fd; struct sockaddr_in server_addr; struct epoll_event events[MAX_EVENTS];
// 创建socket
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd == -1) {
printf("Failed to create socket.
"); return -1; }
// 设置服务器地址
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(8080);
// 绑定socket到服务器地址
int bind_result = bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
if (bind_result == -1) {
printf("Failed to bind socket.
"); close(server_fd); return -1; }
// 开始监听连接
int listen_result = listen(server_fd, 5);
if (listen_result == -1) {
printf("Failed to listen on socket.
"); close(server_fd); return -1; }
// 创建epoll实例
epoll_fd = epoll_create1(0);
if (epoll_fd == -1) {
printf("Failed to create epoll instance.
"); close(server_fd); return -1; }
// 将服务器socket添加到epoll事件集合中
struct epoll_event server_event;
server_event.events = EPOLLIN;
server_event.data.fd = server_fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &server_event) == -1) {
printf("Failed to add server socket to epoll.
"); close(server_fd); close(epoll_fd); return -1; }
while (1) {
// 等待事件发生
int num_events = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
if (num_events == -1) {
printf("Error in epoll_wait.
"); break; }
// 处理所有就绪事件
for (int i = 0; i < num_events; i++) {
if (events[i].data.fd == server_fd) {
// 有新的连接请求
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &client_addr_len);
if (client_fd == -1) {
printf("Failed to accept connection.
"); break; }
// 将新的客户端连接添加到epoll事件集合中
struct epoll_event client_event;
client_event.events = EPOLLIN;
client_event.data.fd = client_fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &client_event) == -1) {
printf("Failed to add client socket to epoll.
"); close(client_fd); break; } } else { // 有客户端请求 handle_request(events[i].data.fd); } } }
// 关闭服务器socket和epoll实例
close(server_fd);
close(epoll_fd);
return 0;
}
// 该示例代码是一个简单的 HTTP 服务器,仅用于演示 epoll 轮询的使用方法。 // 在实际应用中,可能需要更复杂的请求处理逻辑和错误处理机制。
原文地址: https://www.cveoy.top/t/topic/pSAr 著作权归作者所有。请勿转载和采集!