когда нет доступных потоков (findAvailableThreads () возвращает -1), является ли нормальное поведение, что select () не ожидает своего тайм-аута, и поэтому цикл while итерация выполняется очень быстро, пока не станет доступен новый поток?
Да, потому что при этом условии вы не вызываете accept()
, поэтому вы не меняете состояние прослушивающего сокета.Он останется в читаемом состоянии, пока у него есть клиентское соединение, ожидающее accept()
'ed.
, если да, как я могу избежать этих действительно быстрых итераций?
Позвоните accept()
, прежде чем проверять наличие доступного потока.Если поток недоступен, закройте принятое соединение.
Вместо использования что-то вроде простого sleep () в строке 13, внутри ветви if, есть ли способ позволить select () восстановить свое время ожидания?
Единственный способ - accept()
соединение, которое переводит прослушивающий сокет в читаемое состояние, поэтому у него есть шанс вернуться в нечитаемое состояние.Тайм-аут больше не будет применяться до тех пор, пока сокет не перестанет считываться.
Или даже, есть ли способ полностью отклонить ожидающее входящее соединение?
Единственный способ - сначала accept()
, затем вы можете close()
если нужно.
Попробуйте:
void TCPServer::listenWithTimeout() {
fd_set descrSet;
while (listeningThread.active) {
std::cout << "TCP Server thread is listening..." << std::endl;
FD_ZERO(&descrSet);
FD_SET(mySocketFD, &descrSet);
struct timeval timeout = {1, 0};
int descrAmount = select(mySocketFD + 1, &descrSet, NULL, NULL, &timeout);
if (descrAmount > 0) {
assert(FD_ISSET(mySocketFD, &descrSet));
int newSocketFD = accept(mySocketFD, (struct sockaddr *) &mySocket, &clieAddrssLen);
if (newSocketFD != -1) {
int threadIndx = findAvailableThread();
if (threadIndx < 0) {
close(newSocketFD);
std::cout << "Connection not accepted: no threads available..." << std::endl;
} else {
joinThread(threadIndx);
std::cout << "TCP Client connected..." << std::endl;
connectionThreads[threadIndx].thread = std::thread(TCPServer::startTCPConnectionWithException, std::ref(*this), threadIndx, newSocketFD);
connectionThreads[threadIndx].active = true;
}
}
}
}
std::cout << "TCP Server thread is terminating..." << std::endl;
}