linux IO多路复用
epoll服务端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <netinet/in.h>#define PORT 8080
#define BUF_SIZE 1024
#define MAX_EVENTS 10int main() {int server_fd, epfd;struct sockaddr_in address;int addrlen = sizeof(address);struct epoll_event ev, events[MAX_EVENTS];// 创建epoll实例if ((epfd = epoll_create1(0)) == -1) {perror("epoll_create1 failed");exit(EXIT_FAILURE);}// 创建监听套接字if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);bind(server_fd, (struct sockaddr *)&address, sizeof(address));listen(server_fd, 5);// 注册监听套接字到epoll(监控可读事件)ev.events = EPOLLIN;ev.data.fd = server_fd;if (epoll_ctl(epfd, EPOLL_CTL_ADD, server_fd, &ev) == -1) {perror("epoll_ctl: server_fd");exit(EXIT_FAILURE);}printf("epoll服务端启动,等待连接...\n");while (1) {// 阻塞等待事件(最多等待MAX_EVENTS个)int nfds = epoll_wait(epfd, events, MAX_EVENTS, -1);if (nfds == -1) {perror("epoll_wait failed");exit(EXIT_FAILURE);}// 处理就绪事件for (int i = 0; i < nfds; i++) {if (events[i].data.fd == server_fd) {// 新连接事件int new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen);if (new_socket == -1) {perror("accept failed");continue;}printf("新客户端连接: %d\n", new_socket);// 注册新客户端套接字到epollev.events = EPOLLIN | EPOLLET; // 边缘触发(ET)ev.data.fd = new_socket;if (epoll_ctl(epfd, EPOLL_CTL_ADD, new_socket, &ev) == -1) {perror("epoll_ctl: new_socket");close(new_socket);}} else {// 客户端数据事件int fd = events[i].data.fd;char buffer[BUF_SIZE] = {0};ssize_t valread = recv(fd, buffer, BUF_SIZE, 0);if (valread <= 0) {// 连接关闭或错误,移除epoll并关闭fdepoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);close(fd);printf("客户端断开: %d\n", fd);} else {printf("收到数据(%d): %s\n", fd, buffer);const char* response = "epoll服务端已收到";send(fd, response, strlen(response), 0);}}}}close(epfd);close(server_fd);return 0;
}
epoll客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>#define PORT 8080
#define BUF_SIZE 1024int main() {int sock = 0;struct sockaddr_in serv_addr;char buffer[BUF_SIZE] = {0};if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {perror("socket creation error");exit(EXIT_FAILURE);}serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(PORT);if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {perror("invalid address");exit(EXIT_FAILURE);}// 阻塞连接(connect阻塞)if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {perror("connect failed");exit(EXIT_FAILURE);}// 发送数据const char *msg = "Hello, 服务端";send(sock, msg, strlen(msg), 0);printf("数据已发送\n");// 阻塞接收响应(recv阻塞)ssize_t valread = recv(sock, buffer, BUF_SIZE, 0);printf("收到响应: %s\n", buffer);close(sock);return 0;
}