C epoll 通讯 源代码
时间: 2024-12-25 11:26:06 浏览: 10
Epoll 是 Linux 系统提供的一种高效事件驱动的 I/O 处理模型,用于监控多个文件描述符(如套接字)是否就绪,包括读取、写入等事件。以下是使用 C 语言编写的一个简单 Epoll 示例,它创建了一个服务器监听端口,并通过 Epoll 实现了非阻塞的通信:
```c
#include <stdio.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define MAX_EVENTS 10
#define EPOLL_PORT 8080
typedef struct {
int socket_fd;
struct epoll_event event;
} SocketInfo;
void handle_client(int socket_fd, struct epoll_event* ev) {
char buffer[1024];
ssize_t read_size;
write(socket_fd, "Welcome to the server!\r\n", sizeof("Welcome to the server!\r\n"));
// Read client's message
read_size = read(socket_fd, buffer, sizeof(buffer));
if (read_size > 0)
printf("Received from client: %.*s\n", (int)read_size, buffer);
else
perror("Reading client data");
close(socket_fd);
}
int main() {
int server_socket, epoll_fd;
struct sockaddr_in server_addr, client_addr;
socklen_t client_len = sizeof(client_addr);
char buffer[1024];
SocketInfo sockets[MAX_EVENTS];
// Create a listening socket
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket < 0) {
perror("Creating server socket");
exit(EXIT_FAILURE);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(EPOLL_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("Binding server socket");
close(server_socket);
exit(EXIT_FAILURE);
}
listen(server_socket, 5);
// Create an epoll instance
epoll_fd = epoll_create1(0);
if (epoll_fd < 0) {
perror("Creating epoll");
exit(EXIT_FAILURE);
}
// Add server socket to epoll
sockets[0].socket_fd = server_socket;
sockets[0].event.events = EPOLLIN | EPOLLET;
sockets[0].event.data.fd = server_socket;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sockets[0].socket_fd, &sockets[0].event) < 0) {
perror("Adding server socket to epoll");
close(epoll_fd);
exit(EXIT_FAILURE);
}
// Listen for new connections
while (true) {
int events_num = epoll_wait(epoll_fd, sockets, MAX_EVENTS, -1);
if (events_num <= 0) {
perror("epoll_wait");
break;
}
for (int i = 0; i < events_num; i++) {
if (sockets[i].event.events & EPOLLIN && sockets[i].socket_fd == server_socket) {
// Accept new client connection
client_fd = accept(server_socket, (struct sockaddr*)&client_addr, &client_len);
if (client_fd >= 0) {
printf("Accepted connection from %s:%d\n",
inet_ntoa(client_addr.sin_addr),
ntohs(client_addr.sin_port));
// Add client socket to epoll
sockets[i + 1] = sockets[i]; // Copy existing info
sockets[i + 1].socket_fd = client_fd;
sockets[i + 1].event.events = EPOLLIN | EPOLLET;
sockets[i + 1].event.data.fd = client_fd;
epoll_ctl(epoll_fd, EPOLL_CTL_MOD, sockets[i + 1].socket_fd, &sockets[i + 1].event);
i++; // Increment index after adding client
} else {
perror("Accepting client");
}
} else if (sockets[i].event.events & EPOLLIN) {
handle_client(sockets[i].socket_fd, &sockets[i].event);
}
}
}
close(epoll_fd);
close(server_socket);
return 0;
}
阅读全文