ошибка отключения клиента epoll - PullRequest
0 голосов
/ 22 июня 2011
for(int i=0; i<event_cnt; i++){

        SocketClient *conn = reinterpret_cast<SocketClient *>(m_events[i].data.ptr);

        if(m_events[i].events & EPOLLRDHUP){
            printf("ServerManager::eventAcceptLoop, EPOLLRDHUP \n");
            removeClient(conn);
            close(conn->getFd());
        }

        if(conn->getFd() == m_serverSocket->getFd()){

            printf("ServerManager::eventAcceptLoop, A Client has been connected \n");

            struct sockaddr_in clnt_adr;
            socklen_t adr_sz = sizeof(clnt_adr);
            int clnt_sock = accept(m_serverSocket->getFd(), (struct sockaddr*)&clnt_adr, &adr_sz);

            SocketClient* client = new SocketClient(clnt_sock);
            if(!addClient(client))
                break;
        }
        else{

            int recv = conn->recv();

            if(recv <= 0){
                removeClient(conn);
                close(conn->getFd());
            }
            else{
                printf("ServerManager::eventAcceptLoop, A message has been received \n");
                vector<char> data = conn->getData();
                addWork(conn, data);
            }
        }
    }//for loop end

Я работаю над сетевым программированием с использованием epoll.У меня есть этот код, он работает нормально, пока клиент не отключен.Я создал простой клиент Java и отправил пакет, и он получил пакет правильно.Проблема в том, что если я попытался отключиться, он каким-то образом получает много событий, таких как EPOLLIN и EPOLLRDHUP.

Я добавил epoll вот так

int addEpollFd(int epfd, SocketClient *socketClient){
    struct epoll_event event;
    event.events = EPOLLIN|EPOLLRDHUP;
    event.data.ptr = reinterpret_cast<void*>(socketClient);
    return epoll_ctl(epfd, EPOLL_CTL_ADD, socketClient->getFd(), &event);
}

Что может вызвать эту проблему?и как мне это исправить?Заранее спасибо ...

edit

Удаляю клиента вот так

bool ServerManager::removeClient(SocketClient *clientSock){
    if(removeEpollFd(m_epfd, clientSock) < 0){
        perror("ServerManager::removeClient, remove_epoll error \n");
        return false;
    }
    if(!m_clientList->remove(clientSock))
        perror("ServerManager::removeClient, client remove error \n");

    printf("ServerManager::removeClient, close client \n");
    return true;
}
...