【问题标题】:Could you recommend some guides about Epoll on Linux [closed]你能推荐一些关于 Linux 上 Epoll 的指南吗?
【发布时间】:2010-09-06 20:02:48
【问题描述】:

我需要了解 Epoll On linux System。

您能推荐一些关于 epoll 库的手册或指南吗?

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

帮帮我。并感谢您阅读。

【问题讨论】:

  • 我已经广泛使用了 epoll(),它很棒。我已经用 128K 活动套接字对其进行了测试,它的性能非常好。如果您有任何具体问题,请提出。
  • 谢谢。你做得很好! 128k 插座!!惊人的!您能告诉我如何接受 128k 活动套接字的任何评论或示例吗? ps:回答太长了。对不起。
  • @Simon:当您接受来自具有不同 IP 的客户端的连接时,很容易获得这么多。每个 IP 理论上限制为 64K 端口,实际上可能是 20-30K。您可能需要多个测试系统。
  • 我觉得这个问题不应该被关闭,它要求了解如何使用epoll

标签: c++ linux epoll


【解决方案1】:

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

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

另外,the man pages

【讨论】:

  • 第二个和第三个链接坏了。
  • 第三个链接指向钓鱼页面
【解决方案2】:
#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), '\0', 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;
}

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

【讨论】:

  • 你不能像这样在 cpp 中使用 calloc。您应该像这样使用 (epoll_event*) 进行转换: events =(epoll_event*) calloc(MAX_CON, sizeof(struct epoll_event));
  • Ughh.. 代码需要清理大量未使用的变量,只有在使用 select 时才需要
猜你喜欢
  • 1970-01-01
  • 2011-01-24
  • 2010-11-27
  • 2010-09-12
  • 2010-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多