考虑以下类方法:
void TCPServer::listenWithTimeout() {
fd_set descrSet;
struct timeval timeout = {1, 0};
while (listeningThread.active) {
std::cout << "TCP Server thread is listening..." << std::endl;
FD_ZERO(&descrSet);
FD_SET(mySocketFD, &descrSet);
int descrAmount = select(mySocketFD + 1, &descrSet, NULL, NULL, &timeout);
if (descrAmount > 0) {
assert(FD_ISSET(mySocketFD, &descrSet));
int threadIndx = findAvailableThread();
if (threadIndx < 0) {
std::cout << "Connection not accepted: no threads available..." << std::endl;
} else {
joinThread(threadIndx);
int newSocketFD = accept(mySocketFD, (struct sockaddr *) &mySocket, &clieAddrssLen);
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;
}
以下是一些问题:
当没有可用线程时(findAvailableThreads()
返回-1
),select()
不等待超时是正常行为,因此{{1} }循环真正快速迭代,直到有新线程可用?
如果是,我如何避免这些真正快速的迭代?除了在while
分支内的第13行使用简单的sleep()
之外,还有没有办法让if
恢复其超时?甚至没有办法完全拒绝传入的连接挂起?
答案 0 :(得分:2)
当没有可用线程时(findAvailableThreads()返回-1),select()不等待其超时是正常行为,因此while循环真正快速迭代直到有新线程可用?
是的,因为在这种情况下,您不会调用accept()
,所以您不会更改侦听套接字的状态。只要它具有等待accept()
建立的客户端连接,它将保持可读状态。
如果是,我如何避免这些真正快速的迭代?
在检查可用线程之前调用accept()
。如果没有可用的线程,请关闭接受的连接。
不是在if分支中的第13行使用简单的sleep()之类的方法,而是有办法让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;
}