简体   繁体   English

epoll_wait收到未知事件

[英]epoll_wait receiving an unknown event

I have written a simple TCP server socket and added the fd to the epoll_cntl . 我编写了一个简单的TCP服务器套接字,并将fd添加到epoll_cntl After the client is connected, the accept fd is also added to the epoll_cntl . 客户端连接后,accept fd也添加到epoll_cntl

When the client is closed, I am receiving an unknown event through epoll_wait . 当客户端关闭时,我通过epoll_wait接收到未知事件。 epoll event is receiving an event as 5 (kindly grep for the string "Issue seen here" in the code below. epoll事件接收的事件为5(在下面的代码中,grep为字符串“ Issue seen here”)

Can someone help me out in understanding, why the epoll is receiving such an event? 有人可以帮助我理解为什么epoll会收到这样的事件吗?

Here's my code: 这是我的代码:

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;
}

The events field is a bitmask. 事件字段是一个位掩码。 EPOLLIN is 1. EPOLLOUT is 4. Therefore EPOLLIN | EPOLLOUT EPOLLINEPOLLOUT为4 EPOLLIN | EPOLLOUT EPOLLIN | EPOLLOUT is 5. EPOLLIN | EPOLLOUT为5。

So the file descriptor is both readable and writable. 因此,文件描述符是可读可写的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM