while(m_severRun){
printf("ServerManager::eventAcceptLoop, epoll_wait\n");
int event_cnt = epoll_wait(m_epfd, m_events, EPOLL_SIZE, -1);
if(event_cnt == -1){
perror("epoll_wait error \n");
break;
}
for(int i=0; i<event_cnt; i++){
SocketClient *conn = reinterpret_cast<SocketClient *>(m_events[i].data.ptr);
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{
if(m_events[i].events & EPOLLRDHUP){
printf("ServerManager::eventAcceptLoop, EPOLLRDHUP \n");
removeClient(conn);
close(conn->getFd());
continue;
}
if(m_events[i].events & EPOLLIN){
printf("ServerManager::eventAcceptLoop, EPOLLIN \n");
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);
}
}
if(m_events[i].events & EPOLLERR)
printf("ServerManager::eventAcceptLoop, EPOLLERR \n");
}
}//for loop end
}//while loop end
Я работаю над сетевым программированием (tcp) и у меня есть этот код. Я впервые использую epoll, поэтому я не уверен, что этот дизайн правильный. Кроме того, я использую пул потоков (5 дочерних потоков) и всякий раз, когда я читаю данные из epoll, я помещаю их в очередь в пуле потоков. Проблема в том, что в функции чтения я вижу проблему с горлышком бутылки.
В функции чтения он вызывает ObserveSocket
int SocketClient::ObserveSock(int sock, int timeout){
printf("SocketClient::ObserveSock called\n");
fd_set reads;
int fd_max;
struct timeval _timeout;
FD_ZERO(&reads);
FD_SET(sock, &reads);
fd_max = sock + 1;
_timeout.tv_sec = timeout;
_timeout.tv_usec = 0;
return select(fd_max, &reads, 0, 0, &_timeout);
}
Он наблюдает за сокетом, и если в течение определенного времени нет сигнала, он возвращает 0, чтобы закрыть сокет. Я подумал, что мне нужен этот код для обнаружения неожиданного отключения пользователя или повреждения данных (клиент отправил 100 байтов, но сервер получил 90 байтов, тогда сервер будет ждать последние 10 байтов, которые не будут получены).
Буду очень признателен, если вы, ребята, расскажете мне, как я могу решить проблему с горлышком бутылки и любые проблемы с архитектурой.
Я также поищу любой хороший учебник, который использует epoll и подробно описывает обработку исключений.
Заранее спасибо.
EDIT
Внутри функции recv () она просто вызывает функцию чтения, а перед чтением я вызываю ObserveSocket