【问题标题】:udp socket buffer becomes full after calling recvmsg followed by epoll_wait()在调用 recvmsg 后跟 epoll_wait() 后 udp 套接字缓冲区变满
【发布时间】:2013-07-31 20:53:04
【问题描述】:

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

代码 sn-p 如下 -

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() 接收到的每个事件只读取单个消息时,套接字缓冲区会被填满

【问题讨论】:

    标签: c sockets unix udp


    【解决方案1】:

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

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

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

    编辑:偶然发现this 对类似问题的回答。

    【讨论】:

    • 是的。这确实是问题所在。我现在已将 epoll 设置为级别触发。它工作正常。谢谢。
    猜你喜欢
    • 2014-08-17
    • 1970-01-01
    • 2012-07-12
    • 1970-01-01
    • 2016-04-22
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多