0

我遇到了一个问题,即 UDP 服务器套接字缓冲区被填满。一旦缓冲区已满,数据包就会被丢弃。使用“netstat -anp | grep udp”监控套接字缓冲区大小。UDP 服务器调用 epoll_wait() 后跟 recv_msg()。这是一个非阻塞套接字。

代码片段如下 -

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
}

如果在 while 循环中调用 recvmsg 直到找到 EAGAIN,然后再查找下一个描述符,则问题已解决(即套接字缓冲区未填满)。

知道为什么当从 epoll_wait() 接收到的每个事件仅读取单个消息时,套接字缓冲区会被填满

4

1 回答 1

1

我的位置已经很晚了,但我会尽力让自己理解:)

我将参考 Epoll 的手册页,例如可以在linux.die.net上找到。当与 EPOLLET 一起使用时,epoll 是边缘触发的(EPOLLET 中的 ET)。这意味着它将在状态更改时触发。如果您收到多条消息,但在无限超时调用 epoll_wait() 之前只阅读了第一条消息,那么您基本上就像手册页所描述的那样将自己锁死了。

总结一下:由于 epoll_wait 正在等待更改(从无到某些消息)但已经有可用的消息,因此状态转换和事件将永远不会发生。

编辑:偶然发现这个类似问题的答案。

于 2013-07-31T21:20:41.637 回答