简体   繁体   中英

epoll_wait receiving an unknown event

I have written a simple TCP server socket and added the fd to the epoll_cntl . After the client is connected, the accept fd is also added to the epoll_cntl .

When the client is closed, I am receiving an unknown event through epoll_wait . epoll event is receiving an event as 5 (kindly grep for the string "Issue seen here" in the code below.

Can someone help me out in understanding, why the epoll is receiving such an event?

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 EPOLLIN | EPOLLOUT is 5.

So the file descriptor is both readable and writable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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