免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4013 | 回复: 3
打印 上一主题 下一主题

为何检测不到EPOLLOUT事件??? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-02-03 19:16 |只看该作者 |倒序浏览
epoll循环如下:

while (1) {
    nfds = epoll_wait(kdpfd, events, curfds, -1);
    if (nfds == -1) {
        perror("epoll_wait");
        break;
    } else {
        fprintf(stderr, "===>nfds is: %d\n", nfds);
    }
    for (n = 0; n < nfds; ++n) {
            if (events[n].events & EPOLLIN) {
                if (events[n].data.fd == listener) {
                    fprintf(stderr, "^^^in event: new client[%d]\n", events[n].data.fd);
                    ///////////////////////
                new_fd = accept(listener, (struct sockaddr *) &their_addr,
                                &len);
                if (new_fd < 0) {
                    perror("accept");
                    continue;
                } else {
                    fprintf(stderr, "connection from: %s:%d, sockfd is:%d\n",
                      inet_ntoa(their_addr.sin_addr), ntohs(their_addr.sin_port), new_fd);
                }

                setnonblocking(new_fd);
                ev.events = EPOLLIN | EPOLLET | EPOLLOUT;
                ev.data.fd = new_fd;
                if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, new_fd, &ev) < 0) {
                    fprintf(stderr, "add sockfd '%d' to epoll fail%s\n",
                            new_fd, strerror(errno));
                    return -1;
                }
                curfds++;
                    ///////////////////////
                } else {
                    fprintf(stderr, "^^^in event: old client[%d]\n", events[n].data.fd);
                }
            }
            if (events[n].events & EPOLLOUT) {
                fprintf(stderr, "^^^out event\n");
            }
    }
}


经过测试发现,如果用telnet连接上了两个客户端,在一个客户端上按键盘的话,nfds返回1,返回的这个
fd读事件,写事件都检测到了,(并且每次按键盘,写事件都能检测得到)

问题是: 既然EPOLLOUT事件每次都能检测到,那么如果有两个客户端,nfds的值应该是2啊(因为有两个)
客户端socket都可写,为何nfds总是返回1?

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2009-02-04 10:40 |只看该作者
在手册中提到,EPOLLOUT也跟EPOLLIN一样,要写到EAGAIN才会改变状态,否则不会再触发可写事件的,
一个fd,只有在刚注册后会触发可写事件,以后不会再触发可写事件了,除非你写到EAGAIN,

你的测试为什么每次都会触发可写事件,让我不解。

你检测到可读事件后,并没有对fd进行操作,你接收一下数据试一试。

论坛徽章:
0
3 [报告]
发表于 2009-02-04 10:58 |只看该作者
现在奇怪的是,每当接受一个客户端连接后,我就监听其in和out事件

然后一个客户端向server发送数据触发in事件后,我发现其out事件也触发了

这个和手册的描述似乎不相符(我并没有write直到eagain),为什么有in事件时,out事件也有???

论坛徽章:
0
4 [报告]
发表于 2009-02-04 11:31 |只看该作者
有人甚至说: 你调用write会触发EPOLLOUT事件!!!

--------------------------------------------------
引用: http://www.berkeleydb.net/bbs/re ... ;tid=13&fpage=1
回答3:
EPOLLOUT这个flag的意思是指当你给这个socket发消息的时候,也会触发epoll的event,也就是讲,当你用EPOLLOUT来新加了一个event,在你调用write(this_fd, data, num_data);的时候,epoll_wait中也会返回这个fd,在一般情况下,EPOLLOUT是没有太大的实际作用的,一般用EPOLLIN就好了,如果你只设置了EPOLLIN,当有消息进来时,epoll_wait就会返回一个读的事件,你收到这个事件之后,再调用read(this_fd, in_buffer, in_buffer_len);即可。
--------------------------------------------------
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP