C++ 你能推荐一些关于 Linux 上 Epoll 的指南吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27247/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:19:18  来源:igfitidea点击:

Could you recommend some guides about Epoll on Linux

c++linuxepoll

提问by Simon Kim

I need to know about Epoll On linux System.

我需要了解 Linux 系统上的 Epoll。

Could you recommend manual or guides about epoll library?

您能否推荐有关 epoll 库的手册或指南?

need more detailed guides. it's better to have some examples.

需要更详细的指南。最好有一些例子。

help me. and Thank you for reading.

帮我。并感谢您的阅读。

采纳答案by Ryan Guest

Here's an introduction to Epoll, a pretty basic tutorial: http://blog.kovyrin.net/2006/04/13/epoll-asynchronous-network-programming/

这是 Epoll 的介绍,一个非常基础的教程:http://blog.kovyrin.net/2006/04/13/epoll-asynchronous-network-programming/

A more complete example can be found here: https://banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c/

一个更完整的例子可以在这里找到:https: //banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c/

Also, the man pages

此外,手册页

回答by Viswesn

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/epoll.h>

#define PORT 1500 

#define MAX_CON (1200)

static struct epoll_event *events;

int main(int argc, char *argv[])
{
    fd_set master;
    fd_set read_fds;
    struct sockaddr_in serveraddr;
    struct sockaddr_in clientaddr;
    int fdmax;
    int listener;
    int newfd;
    char buf[1024];
    int nbytes;
    int addrlen;
    int yes;
    int epfd = -1;
    int res = -1;
    struct epoll_event ev;
    int i=0;
    int index = 0;
    int client_fd = -1;

    int SnumOfConnection = 0;
    time_t Sstart, Send;

    if((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
            perror("Server-socket() error lol!");
            exit(1);
    }

    if(setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
    {
            perror("Server-setsockopt() error lol!");
            exit(1);
    }
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = INADDR_ANY;
    serveraddr.sin_port = htons(PORT);
    memset(&(serveraddr.sin_zero), '##代码##', 8);
    if(bind(listener, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1)
    {
            perror("Server-bind() error lol!");
            exit(1);
    }
    if(listen(listener, 10) == -1)
    {
            perror("Server-listen() error lol!");
            exit(1);
    }
    fdmax = listener; /* so far, it's this one*/

    events = calloc(MAX_CON, sizeof(struct epoll_event));
    if ((epfd = epoll_create(MAX_CON)) == -1) {
            perror("epoll_create");
            exit(1);
    }
    ev.events = EPOLLIN;
    ev.data.fd = fdmax;
    if (epoll_ctl(epfd, EPOLL_CTL_ADD, fdmax, &ev) < 0) {
            perror("epoll_ctl");
            exit(1);
    }
    //time(&start);
    for(;;)
    {
            res = epoll_wait(epfd, events, MAX_CON, -1);
            client_fd = events[index].data.fd;

            for (index = 0; index < MAX_CON; index++) {
                    if(client_fd == listener)
                    {
                            addrlen = sizeof(clientaddr);
                            if((newfd = accept(listener, (struct sockaddr *)&clientaddr, &addrlen)) == -1)
                            {
                                    perror("Server-accept() error lol!");
                            }
                            else
                            {
                            //      printf("Server-accept() is OK...\n");
                                    ev.events = EPOLLIN;
                                    ev.data.fd = newfd;
                                    if (epoll_ctl(epfd, EPOLL_CTL_ADD, newfd, &ev) < 0) {
                                            perror("epoll_ctl");
                                            exit(1);
                                    }
                            }
                            break;
                    }
                    else
                    {
                            if (events[index].events & EPOLLHUP)
                            {
                                    if (epoll_ctl(epfd, EPOLL_CTL_DEL, client_fd, &ev) < 0) {
                                            perror("epoll_ctl");
                                    }
                                    close(client_fd);
                                    break;
                            }
                            if (events[index].events & EPOLLIN)  {
                                    if((nbytes = recv(client_fd, buf, sizeof(buf), 0)) <= 0)
                                    {
                                            if(nbytes == 0) {
                                            //      printf("socket %d hung up\n", client_fd);
                                            }
                                            else {
                                                    printf("recv() error lol! %d", client_fd);
                                                    perror("");
                                            }

                                            if (epoll_ctl(epfd, EPOLL_CTL_DEL, client_fd, &ev) < 0) {
                                                    perror("epoll_ctl");
                                            }
                                            close(client_fd);
                                    }
                                    else
                                    {
                                            if(send(client_fd, buf, nbytes, 0) == -1)
                                                    perror("send() error lol!");
                                    }
                                    break;
                            }
                    }
            }
    }
    return 0;
}

I wrote this program for testing and I was able to connect more than 80k connections and I find average system load only to 0.27%.

我编写了这个程序进行测试,我能够连接超过 80k 个连接,我发现平均系统负载仅为 0.27%。