0

I am getting an issue where UDP server socket buffer is getting filled up. Once the buffer is full, packets are getting dropped. socket buffer size is monitored with "netstat -anp | grep udp". UDP server calls epoll_wait() followed by recv_msg(). It's a non-blocking socket.

code snippet is given below -

struct epoll_event ev = {(unsigned int)0};
ev.events = (unsigned int) (EPOLLIN | EPOLLET);
ev.data.fd = iSockFd;
int m_sdEpoll = epoll_create(1);

if(epoll_ctl(m_sdEpoll, EPOLL_CTL_ADD, iSockFd, &ev)<0)
{
    cout << "Epoll insertion error for sd  : " << iSockFd << endl;;
}

while( 1 )
{
    struct epoll_event events[1];
    int noEvt = epoll_wait(m_sdEpoll, events, 1 , -1);
    if(noEvt<0)
    {
        cout << "epoll_wait error no : "<< endl;
        continue;
    }
    for(int i=0; i<noEvt; i++)
    {
        int sd = events[i].data.fd; 

        int recv_bytes = recvmsg(sd, &msg, 0);

    } // end of for loop
}

The problem is fixed ( i.e socket buffer doesn't fillup ) if the recvmsg is called in while loop till EAGAIN is found before going for next descriptor.

Any idea why socket buffer gets fill up when for each event received from epoll_wait() only single message is read

1 Answers1

1

It's getting late where I'm at, but I'll try to make myself understood :)

I will refer to the man pages for Epoll, which can be found on linux.die.net for example. The epoll, when used with EPOLLET is edge triggered (the ET in EPOLLET). This means that it will trigger on a change in the state. If you receive multiple messages but only read the first one before calling epoll_wait() with an infinite timeout you have basically dead-locked yourself as the man page describes.

To summarize: Since the epoll_wait is waiting for a change (from none to some messages) but there already are messages available, the state transition and thereby the event will never occur.

Edit: Stumbled upon this answer to a similar question.

Community
  • 1
  • 1
Icermann
  • 181
  • 3