即使我已经消耗了所有的阅读器缓冲区,epoll_wait()也会在EPOLLIN上唤醒

时间:2013-11-02 16:51:37

标签: sockets

你好我在这个问题上生气,因为我使用的是一个简单的模式。 好吧,我有一个无限的时间,我在服务器套接字和已连接的套接字上使用epoll_wait。如果新套接字发送连接请求,则一切正常;我的问题是当连接套接字(现在我只是使用一个套接字发送390k数据包)发送数据:如果我使用EPOLLONESHOT或EPOLLET,在使用该套接字上的所有请求缓冲区,重置套接字或在recv上接收EAGAIN后无关紧要( ),epoll_wait总是用错误的缓冲区再次唤醒! 我的服务器使用线程池,但现在只是一个完成所有工作的线程(为了简化测试):

while (TRUE) {
        int num = epoll_wait(efd, events, MAX_EVENTS, -1);
        for (int i = 0; i < num; i++) { // ciclo epoll()
            if (events[i].events & EPOLLERR || events[i].events & EPOLLHUP || !(events[i].events & EPOLLIN)) {
                fprintf (stderr, "epoll error on socket: closed\n");
                s = epoll_ctl(efd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
            }
            else if (events[i].data.fd == serverSocket) { 
                while (TRUE) {
                    newInfoClient = server->m_bgServer->AcceptClient(&newSocketClient);
                    if (newInfoClient == NULL) { // nessun client
                        break;
                    }
                    else { 
                            printf("\nSocket accettato: %d", newSocketClient);
                            s = CSocket::MakeNonBlocking(newSocketClient);
                            if (s == -1)
                                abort();
                            event.data.fd = newSocketClient;
                            event.events = EPOLLIN | EPOLLET;
                            s = epoll_ctl(efd, EPOLL_CTL_ADD, newSocketClient, &event);
                            if (s == -1) {
                                abort();
                            }
                } 
            }
            else { 
                AbstractTcpServerGame::DownloadTcpRequest(client);
            }
        }
    }

我刚刚省略了一些检查和其他内部代码。     AbstractTcpServerGame :: DownloadTcpRequest(...) 这个函数只是一个recv in循环来拯救我自己的头,获取缓冲体并且只是为了验证外部循环的空缓冲区我调用一个返回-1的简单recv()(errno = EAGAIN或EWOULDBLOCK)。 在此之后,当我在EPOLLONESHOT情况下使用DownloadTcpRequest()中的epoll_ctr()重新插入套接字时,当它返回epoll_wait()时会在同一个套接字上再次唤醒!这是我的执行日志:

New socket (6) request (errno 11)  <--- when epoll_wait() emits EPOLLIN on socket 6
Download of 18 bytes (socket 6) <-- inside AbstractTcpServerGame::DownloadTcpRequest()
Download of 380k (socket 6) <-- another recv() loop to rescue body request
------------------- empty buffer on socket 6 ----------- <-- dummy recv to show empty buffer
New socket (6) request (errno 11)  
Download of 18 bytes (socket 6) 
Download of -1556256155 (socket 6) 
Error on socket 6 (bad::alloc exception)

客户端发送398k(18个标题+正文)并且所有数据都正确接收,如上图所示,但重新插入套接字或使用EPOLLET,epoll_wait()会生成另一个请求,我不知道这些内容在哪里是不正确的!

0 个答案:

没有答案