请问用epoll同时监视fd的读和写在可靠性上没啥问题吧

29 views
Skip to first unread message

机器猫

unread,
May 21, 2006, 2:45:12 AM5/21/06
to 高性能网络编程邮件列表
找来一段网上广为转贴的代码:

for ( ; ; ) {

//等待epoll事件的发生

nfds=epoll_wait(epfd,events,20,500);

//处理所发生的所有事件

for(i=0;i<nfds;++i)

{

if(events[i].data.fd==listenfd)

{

connfd = accept(listenfd,(sockaddr *)&clientaddr,
&clilen);

if(connfd<0){

perror("connfd<0");

exit(1);

}

setnonblocking(connfd);

char *str = inet_ntoa(clientaddr.sin_addr);

std::cout<<"connect from "<_u115 ?tr<<std::endl;

//设置用于读操作的文件描述符

ev.data.fd=connfd;

//设置用于注测的读操作事件

ev.events=EPOLLIN|EPOLLET;

//注册ev

epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);

}

else if(events[i].events&EPOLLIN)

{

if ( (sockfd = events[i].data.fd) < 0) continue;

if ( (n = read(sockfd, line, MAXLINE)) < 0) {

if (errno == ECONNRESET) {

close(sockfd);

events[i].data.fd = -1;

} else

std::cout<<"readline error"<<std::endl;

} else if (n == 0) {

close(sockfd);

events[i].data.fd = -1;

}

//设置用于写操作的文件描述符

ev.data.fd=sockfd;

//设置用于注测的写操作事件

ev.events=EPOLLOUT|EPOLLET;

//修改sockfd上要处理的事件为EPOLLOUT

epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);

}

else if(events[i].events&EPOLLOUT)

{

sockfd = events[i].data.fd;

write(sockfd, line, n);

//设置用于读操作的文件描述符

ev.data.fd=sockfd;

//设置用于注测的读操作事件

ev.events=EPOLLIN|EPOLLET;

//修改sockfd上要处理的事件为EPOLIN

epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);

}

}

}


为发现他的作者在添加每个event的时候都是用ev.events=EPOLLIN|EPOLLET;

然后在发现一个fd可读时ev.events=EPOLLOUT|EPOLLET;
在一个fd可写时ev.events=EPOLLIN|EPOLLET;

我不懂他这么做有什么考虑

我的想法很简单:
在添每个fd时都ev.events=EPOLLIN|EPOLLOUT|EPOLLET;
然后该读就读,该写就写,不再反复调用epoll_ctl来更改

我这么做可行吗?

SevenCat

unread,
May 21, 2006, 3:06:18 AM5/21/06
to 高性能网络编程邮件列表
因为他是echo服务器啊。
有时候你没数据发的时候总该要改的。

机器猫

unread,
May 21, 2006, 3:26:44 AM5/21/06
to 高性能网络编程邮件列表
也就是他做的是UNP上的echo的epoll版吧
我说里面没有用到的变量maxi这么眼熟呢,呵呵

我如果这么写echo server,是否正确?
...
for(;;){
nfds=epoll_wait(epfd,events,20,500);
for(i=0;i<nfds;i++){
if(events[i].data.fd==listenfd){
...
ev.events=EPOLLIN|EPOLLOUT|EPOLLET;
...
}else if((events[i].events&EPOLLIN)){
...


if ( (n = read(sockfd, line, MAXLINE)) < 0) {

...
}
write(sockfd,line, n);
}
}

也就是说在EPOLLIN发生时,接收到数据后,立刻发回原sockfd,这样不就实现了echo了吗?
我实验好像不成功

晖明甘

unread,
May 27, 2006, 10:58:00 PM5/27/06
to dev4s...@googlegroups.com
不会有问题的。

2006/5/21, 机器猫 <cwin...@gmail.com>:

Togo

unread,
May 29, 2006, 8:02:22 AM5/29/06
to 高性能网络编程邮件列表
如果使用ev.events=EPOLLIN|EPOLLOUT|EPOLLET添加
连接成功后,fd是可写的,这样每次epoll调用都会返回fd可写,根本不会阻塞
Reply all
Reply to author
Forward
0 new messages