如果多连接Web服务器中存在一段时间不活动,请关闭套接字

时间:2012-09-05 19:42:52

标签: c sockets http-1.1

我正在构建一个可以接受和处理多个客户端连接的Web服务器。我正在使用select()
现在正在进行,如果某个特定的连接套接字没有任何活动(发送或recv),我想关闭它。因此,如果一段时间内没有来自连接客户端的请求,我将关闭套接字。有多个这样的连接套接字,我需要对每个套接字进行监控。

我需要此功能来创建持久连接,因为我的网络服务器必须支持HTTP 1.1

这样做的最佳方式是什么?

2 个答案:

答案 0 :(得分:1)

我建议将调用超时设置为select,直到下一个套接字超时为止。然后,如果超时,关闭空闲套接字,然后重复。像这样的伪代码:

timeout = default_timeout;
foreach(socket s)
{
    timeout = min(timeout, (s.last_send_or_recv_time + IDLE_TIMEOUT - now()));
}

result = select(..., timeout);
if(result == 0)
{
    foreach(socket s)
    {
        if(now() - s.last_send_or_recv_time >= IDLE_TIMEOUT)
        {
            close(s);
            remove_from_socket_list(s);
        }
    }
}
else
{
    // Handle received data, update last_send_or_recv_time, etc.
}

答案 1 :(得分:1)

如果您正在使用线程和阻塞模式,您只需要在套接字上设置合适的SO_RCVTIMEOUT,当read()使用errno == EAGAIN/EWOULDBLOCK返回-1时,超时已经发生,所以你只需关闭套接字并退出线程。

如果您使用的是select(),那就更复杂了。 Adam Rosenfield的建议在表面看起来似乎有道理,但实际上,如果其他套接字足够忙,select()超时可能根本不会发生,或者至少在套接字实际变得太死之后不会发生很多分钟。如果要严格执行超时,就像在服务器中那样,必须将最后读取时间与每个套接字关联,并在select()循环的底部迭代fd设置挑选那些 not 准备好的fds,检查他们的上次阅读时间,并关闭那些已经死亡的时间。