通过epoll处理监听socket
以下所有内容均来自 man epoll
页面:
函数 do_use_fd() 使用新的 就绪文件描述符 直到 EAGAIN 由 read(2) 或 write(2) 返回。
ET触发的代码示例:
for(;;) {
nfds = epoll_wait(kdpfd, events, maxevents, -1);
for(n = 0; n < nfds; ++n) {
if(events[n].data.fd == listener) {
client = accept(listener, (struct sockaddr *) &local,
&addrlen);
if(client < 0){
perror("accept");
continue;
}
setnonblocking(client);
ev.events = EPOLLIN | EPOLLET;
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = client;
if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, client, &ev) < 0) {
fprintf(stderr, "epoll set insertion error: fd=%d\n",
client);
return -1;
}
}
else
do_use_fd(events[n].data.fd);
}
}
因此,对于读/写
操作,我们应该通过循环直到收到EAGAIN
来完成;但为什么不是接受
的情况如何?
IMO,当有多个客户端套接字等待接受时,上面的代码将错过一些请求,因为它只接受 1 客户端套接字,我们还应该将其包装在一个循环中,直到 EAGAIN收到。
或者也许我缺少什么?
All below is from man epoll
page:
The function do_use_fd() uses the new
ready file descriptor
until EAGAIN is returned by either read(2) or write(2).
Code example for ET triggered :
for(;;) {
nfds = epoll_wait(kdpfd, events, maxevents, -1);
for(n = 0; n < nfds; ++n) {
if(events[n].data.fd == listener) {
client = accept(listener, (struct sockaddr *) &local,
&addrlen);
if(client < 0){
perror("accept");
continue;
}
setnonblocking(client);
ev.events = EPOLLIN | EPOLLET;
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = client;
if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, client, &ev) < 0) {
fprintf(stderr, "epoll set insertion error: fd=%d\n",
client);
return -1;
}
}
else
do_use_fd(events[n].data.fd);
}
}
So for read/write
operation,we should do it by looping until a EAGAIN
is received;but why it's not the case for accept
?
IMO the above code will miss some requests when there're multiple client sockets waiting to be accepted, as it accepts only 1 client socket, we should also wrap it in a loop until EAGAIN
received.
Or maybe is there something I'm missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看看
epollfd
中监听器socket是如何添加的:它不是添加在edge-triggered中,而是添加在level-triggered中。因此,在
EAGAIN
之前不需要循环。Look at how the listener socket is added to the
epollfd
:It's not added in edge-triggered, it's added in level-triggered. So no need for a loop until
EAGAIN
on that one.