一个简单的epoll的服务端程序

epoll是一种事件驱动的I/O模型,它可以用来处理多个客户端连接。下面是一个简单的epoll服务端程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <fcntl.h>
​
#define BUF_SIZE 4
#define EPOLL_SIZE 50
​
int setNonBlockingMode(int fd) {
    int flag = fcntl(fd, F_GETFL, 0);
    fcntl(fd, F_SETFL, flag | O_NONBLOCK);
    return 0;
}
​
void errorHandling(const char *message) {
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}
​
int main(int argc, char *argv[]) {
    int servSock, clntSock;
    struct sockaddr_in servAddr, clntAddr;
    socklen_t clntAddrSize;
    char buf[BUF_SIZE];
    struct epoll_event *epEvents;
    struct epoll_event event;
    int epfd, eventCnt, i;
​
    if (argc != 2)
        errorHandling("Usage: ./server <port>");
​
    servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (servSock == -1)
        errorHandling("socket() error");
​
    memset(&servAddr, 0, sizeof(servAddr));
    servAddr.sin_family = AF_INET;
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servAddr.sin_port = htons(atoi(argv[1]));
​
    if (bind(servSock, (struct sockaddr *) &servAddr, sizeof(servAddr)) == -1)
        errorHandling("bind() error");
​
    if (listen(servSock, 5) == -1)
        errorHandling("listen() error");
​
    epfd = epoll_create(EPOLL_SIZE);
    epEvents = malloc(sizeof(struct epoll_event) * EPOLL_SIZE);
​
    event.events = EPOLLIN;
    event.data.fd = servSock;
    epoll_ctl(epfd, EPOLL_CTL_ADD, servSock, &event);
​
    while (1) {
        eventCnt = epoll_wait(epfd, epEvents, EPOLL_SIZE, -1);
        if (eventCnt == -1)
            errorHandling("epoll() error");
​
        for (i = 0; i < eventCnt; ++i) {
            if (epEvents[i].data.fd == servSock) {
                clntAddrSize = sizeof(clntAddr);
                clntSock = accept(servSock, (struct sockaddr *) &clntAddr, &clntAddrSize);
                setNonBlockingMode(clntSock);
​
                event.events = EPOLLIN | EPOLLET;
                event.data.fd = clntSock;
                epoll_ctl(epfd, EPOLL_CTL_ADD, clntSock, &event);
                printf("Connected client: %d\n", clntSock);
            } else {
                while (1) {
                    int strLen = read(epEvents[i].data.fd, buf, BUF_SIZE);
                    if (strLen == 0) {
                        epoll_ctl(epfd, EPOLL_CTL_DEL, epEvents[i].data.fd, NULL);
                        close(epEvents[i].data.fd);
                        printf("Closed client: %d\n", epEvents[i].data.fd);
                        break;
                    } else if (strLen < 0) {
                        if (errno == EAGAIN)
                            break;
                        errorHandling("read() error");
                    } else {
                        write(epEvents[i].data.fd, buf, strLen);
                    }
                }
            }
        }
    }
​
    close(servSock);
    close(epfd);
    return 0;
}

这个程序创建了一个在指定端口上监听的套接字,然后使用epoll机制来处理多个客户端连接。当客户端连接时,程序将文件描述符添加到epoll实例中。

然后,程序使用epoll_wait()函数来等待任何事件发生,并使用read()和write()函数来处理客户端请求并向客户端发送响应。

本文福利, 免费领取C++学习资料包、技术视频/代码,内容包括(C++基础,网络编程,数据库,中间件,后端开发,音视频开发,Qt开发)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓

猜你喜欢

转载自blog.csdn.net/m0_60259116/article/details/130364088