c - epoll_wait 接收未知事件

标签 c linux sockets epoll

我已经编写了一个简单的 TCP 服务器套接字并将 fd 添加到 epoll_cntl。客户端连接后,accept fd也被添加到epoll_cntl中。

当客户端关闭时,我通过 epoll_wait 接收到一个未知事件。 epoll 事件正在接收一个事件 5(请在下面的代码中搜索字符串 “Issue seen here”

有人可以帮助我理解为什么 epoll 会收到这样的事件吗?

这是我的代码:

int ControllerTask()
{
    int retval = 0;
    int res = 0;
    static struct epoll_event ev;

    g_epfd = epoll_create1(0);

    /* Create TCP Server Socket */
    retval = createTcpServerSock();
    if(retval < 0)
    {
        return 0;
    }
    ev.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLERR | EPOLLHUP | EPOLLET;
    ev.data.fd = g_server_fd[0];
    res = epoll_ctl(g_epfd, EPOLL_CTL_ADD, g_server_fd[0], &ev);
    acceptIncomingData();
}

int createTcpServerSock()
{
    int retval = -1;
    struct sockaddr_in addr;
    int sockOpt = 0;
    int reuse = 1;
    do
    {
        if((g_server_fd[0] = socket(AF_INET, SOCK_STREAM, 0)) == 0)
        {
            perror("sock_failed");
            return 0;
        }

        sockOpt = fcntl(g_server_fd[0], F_GETFL);
        if(sockOpt < 0)
            break;

        sockOpt |= O_NONBLOCK;

        if (fcntl(g_server_fd[0], F_SETFL, sockOpt) < 0)
            break;

        if ((retval = setsockopt(g_server_fd[0], SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse))) < 0)
            break;

        if ((retval = setsockopt(g_server_fd[0], SOL_SOCKET, SO_KEEPALIVE, (const char*)&reuse, sizeof(reuse))) < 0)
            break;

        memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = inet_addr("127.0.0.1");
        addr.sin_port = htons(7000);


        if(bind(g_server_fd[0], (struct sockaddr *)&addr, sizeof(addr)) < 0)
        {
            perror("bind failed");
            break;
        }

        listen(g_server_fd[0], SOMAXCONN);

        retval = 0;
    }while(0);

    return retval;
}


void acceptIncomingData()
{
    struct epoll_event *events;
    int nfds, i, err;
    int n_bytes = 0;

    events = (struct epoll_event *)malloc(sizeof(struct epoll_event) * MAX_EPOLL_EVENTS);
    memset(events, 0, sizeof(struct epoll_event) * MAX_EPOLL_EVENTS);

    g_buff = (void *)malloc(MAX_MSG_SIZE * sizeof(char *));
    memset(g_buff, 0, MAX_MSG_SIZE * sizeof(char *));

    while(1) {
        nfds = epoll_wait(g_epfd, events, MAX_EPOLL_EVENTS, EPOLL_WAIT_TIMEOUT);
        if(!nfds)
        {
            continue;
        }
        else if(nfds < 0)
        {
            perror("epoll_wait");
            return;
        }
        printf("Some data in EPOLL\n");

        for(i = 0; i < nfds; i++) {
            if ((events[i].events & EPOLLERR) ||
                (events[i].events & EPOLLHUP))
            {
                printf("TCP close connection\n");
                closeTcpConnection(events[i].data.fd);
                return;
            }
            else
            {
               else if(EPOLLIN == events[i].events)
                {
                    if(events[i].data.fd == g_server_fd[0])
                    {
                        acceptIncomingConns(events[i].data.fd);
                        printf("Accept incoming data\n");
                        continue;
                    }
                    n_bytes = read(events[i].data.fd, g_buff, sizeof(g_buff));
                    if(n_bytes == -1)
                    {
                        if(errno != EAGAIN)
                        {
                            perror("read");
                        }
                    }
                    else if(n_bytes == 0)
                    {
                        printf("n_bytes = 0\n");
                        continue;
                    }
                    else
                    {
                        printf("n_bytes = %d\n", n_bytes);
                        handleSocketEvents(g_buff);
                    }
                }
                else
                {
                    /* Issue seen here: Receiving event as 5 which is not defined */
                    printf("In else. Event : %d\n", events[i].events);
                }
                }
            }
        }
    }
}

int acceptIncomingConns(int fd)
{
    /* accFd = TCP accept FD */
    int accFd = 0;
    int s, i;
    int sockOpt = 0;
    struct sockaddr in_addr;
    int in_len;
    struct epoll_event event;

    while(1)
    {
        accFd = accept(fd, &in_addr, &in_len);
        if(accFd == -1)
        {
            if((errno == EAGAIN) || (errno == EWOULDBLOCK))
            {
                break;
            }
            else
            {
                perror("accept");
                break;
            }
        }

        g_server_fd[1] = accFd;

        sockOpt = fcntl(accFd, F_GETFL);
        sockOpt |= O_NONBLOCK;
        fcntl(accFd, F_SETFL, sockOpt);

        event.data.fd = accFd;
        event.events = EPOLLIN | EPOLLOUT | EPOLLET | EPOLLERR | EPOLLHUP;
        s = epoll_ctl(g_epfd, EPOLL_CTL_ADD, accFd, &event);
    }
}

void closeTcpConnection(int delFd)
{
    int i = 0;
    close(delFd);
    g_server_fd[1] = 0;

    return;
}

最佳答案

事件字段是一个位掩码。 EPOLLIN 为 1。EPOLLOUT 为 4。因此 EPOLLIN | EPOLLOUT 为 5.

所以文件描述符是可读可写的。

关于c - epoll_wait 接收未知事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49685799/

相关文章:

c - sscanf的返回值

c - eclipse中的静态库链接

c++ - 在 mmap 区域上使用 memcpy 会崩溃,for 循环不会

linux - 如何在 Linux 2.6.35 上从用户模式清除和使 ARM v7 处理器缓存失效

ruby - 如何处理ZeroMQ + Ruby中的线程问题?

cocoa - 在 Mac OSX Lion 10.7.2 中绑定(bind)/监听端口失败

c++ - 当堆栈为空时, 'pop()' 方法应该返回什么?

C链表,丢失元素

linux - linux下使用libdrm读取DisplayPort DDC/CI

java - 如何检索输出流的输出