C++ 正确的超时非块套接字事件处理?
我看不出有人问这种问题。这很奇怪,因为单线程服务器应用程序有很多好处。但是,当服务器处于非块状态时,如何在代码中实现超时系统呢 目前我正在使用这种方法C++ 正确的超时非块套接字事件处理?,c++,linux,sockets,unix,C++,Linux,Sockets,Unix,我看不出有人问这种问题。这很奇怪,因为单线程服务器应用程序有很多好处。但是,当服务器处于非块状态时,如何在代码中实现超时系统呢 目前我正在使用这种方法 while(true) { FD_ZERO(&readfds); FD_SET(server_socket, &readfds); for (std::size_t i = 0; i < cur_sockets.size(); i++) {
while(true)
{
FD_ZERO(&readfds);
FD_SET(server_socket, &readfds);
for (std::size_t i = 0; i < cur_sockets.size(); i++)
{
uint32_t sd = cur_sockets.at(i).socket;
if(sd > 0)
FD_SET(sd, &readfds);
if(sd > max_sd){
max_sd = sd;
}
}
int activity = select( max_sd + 1 , &readfds, NULL , NULL, NULL);
if(activity < 0)
{
continue;
}
if (FD_ISSET(server_socket, &readfds))
{
struct sockaddr_in cli_addr;
uint32_t newsockfd = (uint_fast32_t)accept((int)server_socket,
(struct sockaddr *) &cli_addr,
&clientlength);
if(newsockfd < 1) {
continue;
}
//Ensure we can even accept the client...
if (num_clients >= op_max_clients) {
close(newsockfd);
continue;
}
fcntl(newsockfd, F_SETFL, O_NONBLOCK);
/* DISABLE TIMEOUT EXCEPTION FROM SIGPIPE */
#ifdef __APPLE__
int set = 1;
setsockopt(newsockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *) &set, sizeof(int));
#elif __LINUX__
signal(SIGPIPE, SIG_IGN);
#endif
/* ONCE WE ACCEPTED THE CONNECTION ADD CLIENT TO */
num_clients++;
client_con newCon;
newCon.socket = newsockfd;
time_t ltime;
time(<ime);
newCon.last_message = (uint64_t) ltime;
cur_sockets.push_back(newCon);
}
handle_clients();
}
正如您所知,我已经在客户端成功连接时向客户端添加了一个unix timestap。我正在考虑添加另一个每1秒休眠一次的线程,并简单地检查是否有任何客户端在最长持续时间内没有进行任何发送,但我担心我会遇到瓶颈,因为在处理大量连接时,第二个线程会不断锁定
谢谢,
Ajm.select的最后一个参数是select调用的超时,select的返回代码告诉您它是因为套接字准备就绪还是因为超时而返回的
为了为所有套接字实现自己的超时处理,可以为每个套接字设置一个时间戳,并在任何套接字操作中更新它。然后在调用select之前,计算每个套接字的超时,并使用select调用的最小超时值。这只是基本的想法,可以更有效地实现它,这样您就不需要在调用select之前重新计算所有超时。但是我认为一个单独的线程过度了。真不敢相信答案就在我面前。