【发布时间】:2014-02-16 22:28:48
【问题描述】:
假设我在多个网络端口上监听: 80 带 TCP 81-250 使用 UDP
这需要多种不同的方式来处理输入。
- 端口 80 上的新套接字(将新文件描述符添加到 epoll 列表)
- 从端口 80 的客户端套接字读取
- 从其他 170 个 UDP 端口中的任何一个读取
这是很多不同的句柄,而我想使用 epoll 只对正在更新的句柄做出反应。
有什么办法可以过滤 epoll 事件,让每个事件都得到它需要的句柄,而不需要遍历所有文件描述符?
提前致谢,
有罪
示例代码:
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 个循环可能会非常昂贵。 我希望可以在没有这个的情况下确定该事件。 这可能吗?
【问题讨论】:
-
正在更新是什么意思?您想从描述符的子集中选择事件吗?