我开始了解epoll并想创建一个小服务器来玩它。网上有很多关于它的讨论,但是我无法把握在可靠的文档上......
这是我到目前为止的程序结构(为清楚起见,我已将其清理干净):
int sfd = create_and_bind(PORT_NUMBER);
make_non_blocking(sfd);
listen(sfd);
int efd = epoll_create1(0);
event.data.fd = sfd;
event.events = EPOLLIN | EPOLLET;
epoll_ctl(efd, EPOLL_CTL_ADD, sfd, &event);
struct epoll_event *events = calloc(MAXEVENTS, sizeof event);
int p, pid = 1;
for (p = 0; p < 2; ++i) {
if (pid > 0) {
pid = fork();
}
}
if(pid == 0) {
while(1) {
int n, i;
n = epoll_wait(efd, events, MAXEVENTS, -1);
for(i = 0; i < n; ++i) {
if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) {
// Closing socket
close(events[i].data.fd);
continue;
} else if (sfd == events[i].data.fd) {
// incoming connection
int infd = accept(sfd, &in_addr, &in_len);
// Break while if call blocks
make_socket_non_blocking(infd);
event.data.fd = infd;
event.events = EPOLLIN | EPOLLET;
epoll_ctl(efd, EPOLL_CTL_ADD, infd, &event);
} else {
// Ready to read
ssize_t count = read(events[i].data.fd, buf, sizeof buf);
//
// Here I get some problems
//
if (count == -1) {
/* If errno == EAGAIN, that means we have read all
data. So go back to the main loop. */
if (errno != EAGAIN) {
perror("read");
done = 1;
}
break;
} else if (count == 0) {
/* End of file. The remote has closed the
connection. */
done = 1;
break;
}
if(done) {
close(events[i].data.fd);
}
}
}
}
}
我做了一个简单的分叉客户端,用10个并发连接测试这个,几乎每次都得到一个:
read : Bad file descriptor
我在这里错过了什么吗?
谢谢
PS:我只留下了我认为相关的代码......其余部分是:http://pastebin.com/5VTTuNFT