首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

ubuntu12.04中epoll设为“边沿触发”的疑惑

2013-09-28 
ubuntu12.04中epoll设为“边缘触发”的疑惑学习epoll模型的时候,我的服务器端设置为边缘触发,然后每次epoll_

ubuntu12.04中epoll设为“边缘触发”的疑惑
学习epoll模型的时候,我的服务器端设置为边缘触发,然后每次epoll_wait之后只接收100字节的内容。
客户端连接server之后,发送大于100个字节的内容,按理说服务器监听的这个套接口设为边缘触发之后,应该只会读取一次的,但是实际情况确实把客户端发的东西多次读取出来了。
也就时,我设置为了边缘触发,但是服务器端只读取客户端发来的部分内容,再次epoll_wait还是返回了这个套接字。
下面的server的代码


#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <sys/epoll.h>

#define MAX_FD 10
int getPortFromParam(int argc, char *argv[]);
int main(int argc, char *argv[])
{
int port = getPortFromParam(argc, argv);
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in socksrv;
bzero(&socksrv, sizeof(socksrv));
socksrv.sin_addr.s_addr = htonl(INADDR_ANY);
socksrv.sin_family = AF_INET;
socksrv.sin_port = htons(port);
int result = bind(listenfd, (struct sockaddr*)&socksrv, sizeof(socksrv));
if(result == -1) {
perror("bind error!");
exit(1);
}
result = listen(listenfd, 10);
if(result == -1) {
perror("listen error1");
exit(1);
}

struct epoll_event ev, events[MAX_FD];
int kdpfd = epoll_create(MAX_FD);
ev.events = EPOLLIN;
ev.data.fd = listenfd;
epoll_ctl(kdpfd, EPOLL_CTL_ADD, listenfd, &ev);
while(1) {
int nfds = epoll_wait(kdpfd, events,MAX_FD, -1);
if(nfds == -1) {
perror("eait error.");
printf("%d \n", errno);
exit(1);
}
int i;
for(i = 0; i < nfds; i++) {
if(events[i].data.fd == listenfd) {
int clifd = accept(listenfd, NULL, NULL);
if(clifd < 0) 
continue;
printf("%d connected!\n", clifd);
int flags = fcntl(clifd, F_GETFL, 0);
fcntl(clifd, F_SETFL, flags | O_NONBLOCK);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = clifd;
epoll_ctl(kdpfd, EPOLL_CTL_ADD, clifd, &ev);
} else {
char buf[100] = {0};
int nread = read(events[i].data.fd, buf, sizeof(buf));
if(nread == 0) { //EOF
printf("%d closed!\n", events[i].data.fd);
close(events[i].data.fd);
epoll_ctl(kdpfd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
} else if(nread > 0) {
buf[ nread -1 ] = 0;
printf("%d %s\n", events[i].data.fd, buf);
}
}
}
}
return 0;
}


int getPortFromParam(int argc, char *argv[])
{
if(argc !=  2) {
printf("%s <port>\n", argv[0]);
exit(1);
}
return atoi(argv[1]);
}


然后,客户端连接过来,发送大于100个字节的内容,然后服务器这边的执行结果时这样的:
root@chenjingui-pc:/home/chenjingui/workspace/unp/epoll# ./srv 5757
5 connected!
5 asdfasdfffffffadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
5 daaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaggggggggggggggggggggggggg
5 gggggggggggggggggggggggggggggggggggggggggggggggggrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
5 rrrrrrrrr
epoll Ubuntu
[解决办法]
虽然不知道你在说什么。。。。但是没啥问题@!
[解决办法]
虽然不知道你在说什么,但是感觉很NB。
你提供的缓冲区100个字节 数据到达事件肯定会被触发多次啊,不然你怎么处理的完数据,不然一个事件触发一次,无论ET或者LT
[解决办法]
边缘触发,对recv,一定要recv直到遇到EAGAIN为止。
[解决办法]
边缘触发,只会通知你一次,除非状态发生了改变
或通过MOD强制触发,前提是,其实可读/可写

热点排行