在(预)分叉服务器上使用epoll读取错误

时间:2014-03-11 12:34:35

标签: c linux fork epoll

我开始了解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

0 个答案:

没有答案