如何为 select() 监控的每个套接字设置不同的超时时间?
我目前正在使用 BSD 套接字 API。我想使用 select() 函数来监视 (a) 侦听器套接字,该侦听器套接字使用accept() 等待新连接,以及 (b) 所有客户端套接字通过accept() 或connect() 创建。我希望侦听器套接字没有任何超时,并且希望每个客户端套接字有 120 秒的超时。
使用 select() 函数可以实现这一点吗?它只接受所有套接字的单个超时值,所以我的假设是否定的。如果是这样,我是否注定要创建一个每个套接字在其自己的线程中以阻塞模式运行的服务器?
I am currently using the BSD sockets API. I would like to use the select() function to monitor (a) the listener socket which waits for new connections using accept(), and (b) all the client sockets created via accept() or connect(). I want the listener socket to not have any timeout, and I want each client socket to have a timeout of 120 seconds.
Is this possible using the select() function? It only accepts a single timeout value for all sockets, so my assumption is no. If so, am I doomed to making a server in which each socket runs in blocking mode in its own thread?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为什么不做一个本十年的设计并使用libevent呢?
And why not do a design of this decade and use libevent?
由于
select()
函数的逻辑,您应该向其传递最小的超时时间。如果达到这个最小超时,则相应的套接字超时,您应该处理这种情况。换句话说,超时时间较长的套接字永远不会超时,因为它们没有机会超时:时间是从最后一次select()
调用开始计算的,而不是第一次。寻找线索;您无法通过单个
select()
来完成此操作。Due to the logic of
select()
function, you should pass it minimal timeout of your ones. If this minimal timeout is hit, then the corresponding socket is timeouted and you should handle this situation. In other words, sockets with greater timeouts can never timeout, because they just wont' have chance to: the time is calculated starting from the lastselect()
call, not the first one.Go for threads; you can't do this with a single
select()
.您需要自己跟踪剩余的超时,并将最小超时传递给
select()
。例如,假设您希望侦听套接字上没有超时,并且每个连接的超时为 10 分钟(超时 = 600 秒)。对于每个连接,跟踪该套接字上最后一次活动的时间(以秒为单位),如下所示:
然后可以将每个套接字的剩余超时计算为
last + timeout - curtime
,因此如果当前time 为 2000(秒),每个连接的剩余超时时间分别为 550、590、100 和 598。其中最小值为 100,因此下次在没有其他活动的情况下将出现超时条件,因此将其传递给select()
函数。如果select()
超时到期,那么当您重新计算每个套接字上的剩余超时时,您将发现哪些套接字已超时。You need to keep track of the remaining timeouts yourself, and pass the minimum timeout to
select()
.For example, suppose you want no timeout on the listening socket and a timeout of 10 minutes (timeout = 600 seconds) for each connection. For each connection, keep track of the time of the last activity on that socket in seconds, like this:
The remaining timeout for each socket can then be calculated as
last + timeout - curtime
, so if the current time is 2000 (seconds), the remaining timeout for each connection is 550, 590, 100, and 598 respectively. The minimum of those is 100 so that is the next time that you will have a timeout condition in the absence of other activity, so pass that to theselect()
function. If theselect()
timeout expires then when you recalculate the remaining timeout on each socket you will find which socket(s) have timed out.