gpt4 book ai didi

c++ - 正确的超时非阻塞套接字事件处理?

转载 作者:太空宇宙 更新时间:2023-11-04 09:33:19 24 4
gpt4 key购买 nike

我没有看到有人问过这类问题。这很奇怪,因为单线程服务器应用程序带来了很多好处。但是,当服务器处于非阻塞状态时,我如何能够在我的代码中实现超时系统?

目前我正在使用这种方法。

 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(&ltime);
newCon.last_message = (uint64_t) ltime;

cur_sockets.push_back(newCon);
}

handle_clients();
}

如您所知,我已经在客户端成功连接时向其添加了一个 unix 时间戳。我正在考虑添加另一个每 1 秒休眠一次的线程,并简单地检查是否有任何客户端在最大持续时间内没有进行任何发送,但我担心我会遇到瓶颈,因为第二个线程不断锁定在处理大量连接时。

谢谢,

阿吉姆。

最佳答案

select 的最后一个参数是 select 调用的超时时间,select 的返回码会告诉您它返回是因为套接字已就绪还是超时。

为了对所有套接字实现您自己的超时处理,您可以为每个套接字设置一个时间戳,并在任何套接字操作时更新它。然后在调用 select 之前计算每个套接字的超时并使用 select 调用超时的最小值。这只是基本的想法,可以更有效地实现它,这样您就不需要在调用 select 之前重新计算所有超时。但我认为单独的线程杀伤力过大。

关于c++ - 正确的超时非阻塞套接字事件处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29239330/

24 4 0
文章推荐: linux - 从终端中的 bash 脚本内部调用函数
文章推荐: java - 检查 SQLite 数据库中是否存在几个值
文章推荐: java - 如何防止 Element 变成 Element