假设我正在监听多个网络端口: 80个使用TCP 81-250,使用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次循环,这可能是相当昂贵的。我希望事件可以在没有这个的情况下被识别出来。这个是可能的吗?
发布于 2014-02-17 07:50:04
epoll()告诉您触发事件的确切文件描述符。你不需要去寻找它们。Read the documentation作为一个例子。epoll_wait()为您提供了一个epoll_event结构数组,每个结构对应一个符合要求的文件描述符。epoll_event结构有一个fd成员。您将为EPOLLIN事件注册您的各个套接字,然后每次epoll_wait()报告满意的事件时,您将根据需要仅从报告的套接字中读取。
发布于 2015-06-26 12:08:50
就像“remy”提到的那样,为每个套接字创建自己的结构,并将其添加到事件中。当事件第一次被触发时,参考你的结构并开始处理。
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应该会告诉你所有关于套接字和处理函数的信息。
https://stackoverflow.com/questions/21817592
复制相似问题