A simple epoll server program

epoll is an event-driven I/O model that can be used to handle multiple client connections. The following is a simple epoll server program:

#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;
}

This program creates a socket listening on a specified port, and then uses the epoll mechanism to handle multiple client connections. When a client connects, the program adds a file descriptor to the epoll instance.

Then, the program uses the epoll_wait() function to wait for any event to occur, and uses the read() and write() functions to process client requests and send responses to the client.

The benefits of this article, free C++ learning materials package, technical video/code, including (C++ basics, network programming, database, middleware, back-end development, audio and video development, Qt development) ↓↓↓↓↓↓See below↓↓ Click at the bottom of the article to get it for free↓↓

おすすめ

転載: blog.csdn.net/m0_60259116/article/details/130364088