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
}

次の記述子に進む前に EAGAIN が見つかるまで、while ループで recvmsg が呼び出された場合、問題は修正されました (つまり、ソケット バッファがいっぱいになりません)。

epoll_wait() から受信した各イベントに対して単一のメッセージのみが読み取られるときに、ソケットバッファーがいっぱいになる理由

4

1 に答える 1

1

私がいる場所では遅くなりましたが、私は自分自身を理解させようとします:)

たとえば、 linux.die.netにある Epoll の man ページを参照します。EPOLLET で使用される場合、epoll はエッジ トリガーです (EPOLLET の ET)。これは、状態の変化でトリガーされることを意味します。複数のメッセージを受け取ったが、無限のタイムアウトで epoll_wait() を呼び出す前に最初のメッセージしか読んでいない場合は、man ページで説明されているように、基本的にデッドロック状態になっています。

要約すると、epoll_wait は変更 (メッセージなしからいくつかのメッセージへの変更) を待っていますが、使用可能なメッセージが既に存在するため、状態遷移とそれによるイベントは発生しません。

編集:同様の質問に対するこの回答に出くわしました。

于 2013-07-31T21:20:41.637 に答える