首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何过滤epoll事件?

如何过滤epoll事件?
EN

Stack Overflow用户
提问于 2014-02-17 06:28:49
回答 2查看 2.3K关注 0票数 1

假设我正在监听多个网络端口: 80个使用TCP 81-250,使用UDP

这需要多种不同的输入处理方式。

  • 端口80处的新套接字(将新的文件描述符添加到epoll列表)
  • 从端口80处的客户端套接字读取
  • 从其他170个UDP端口中的任何端口读取

这是非常不同的句柄,而我想使用epoll来只对正在更新的句柄做出反应。

有没有什么方法可以过滤epoll事件,这样每个事件都能得到所需的句柄,而不需要遍历所有文件描述符?

提前谢谢你,

有罪

示例代码:

代码语言:javascript
复制
int epfd = epoll_create( 10 );

int tcpFd = createTCPSocket( 80 );
registerListenEvent( epfd, tcpFd );

int udpFds[ 170 ];
for ( int i = 0; i < 170; i++ ) {
  udpSockets[ i ] = createUdpSocket( 81 + i );
  registerUdpPacketEvent( epfd, udpFds[ i ] );
}

int tcpClientFds[ 256 ];
int tcpClientId = 0;

struct epoll_event events[ 64 ];

while ( 1 ) {
  int nfds = epoll_wait( epfd, events, 64, -1 );
  for ( int i = 0; i < nfds; i++ ) {
    struct epoll_event event = events[ i ];
    int fd = event.data.fd;

    // This kind of filtering can take quite a while
    if ( fd == tcpFd ) {
      int acceptedFd = accept( tcpFd );
      registerTcpClientEvent( epfd, acceptedFd );
      tcpClientFds[ tcpClientId++ ] = acceptedFd;
    } else {
      for ( int i = 0; i < 170; i++ )
        if ( udpFds[ i ] == fd ) {
          handleUdpMessage( fd );
          return;
        }
     for ( int i = 0; i < tcpClientId; i++ ) {
       if ( tcpClientFds[ i ] == fd ) {
         handleTcpMessage( fd );
         return;
       }
     }
    }
  }
}

你可以想象一下,每个事件都要经历170 - 426次循环,这可能是相当昂贵的。我希望事件可以在没有这个的情况下被识别出来。这个是可能的吗?

EN

回答 2

Stack Overflow用户

发布于 2014-02-17 07:50:04

epoll()告诉您触发事件的确切文件描述符。你不需要去寻找它们。Read the documentation作为一个例子。epoll_wait()为您提供了一个epoll_event结构数组,每个结构对应一个符合要求的文件描述符。epoll_event结构有一个fd成员。您将为EPOLLIN事件注册您的各个套接字,然后每次epoll_wait()报告满意的事件时,您将根据需要仅从报告的套接字中读取。

票数 1
EN

Stack Overflow用户

发布于 2015-06-26 12:08:50

就像“remy”提到的那样,为每个套接字创建自己的结构,并将其添加到事件中。当事件第一次被触发时,参考你的结构并开始处理。

代码语言:javascript
复制
    struct epoll_event event = {0, {NULL, 0, 0, 0}};
    int s = 0;

    event.data.fd = tp->task_socket;
    event.data->ptr = tp;
    event.events = EPOLLOUT;

    assert(efd);

    s = epoll_ctl (efd, EPOLL_CTL_DEL, tp->task_socket, &event);

处理部件:

用例EPOLLOUT: tp = (task *)ev->data->ptr;

这个tp应该会告诉你所有关于套接字和处理函数的信息。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21817592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档