c-多个select()以监视多个FD_集
我不是网络编程专家。我基本上有两种客户有不同的暂停时间。我应该使用UDP和连接的套接字进行客户机-服务器通信 问题有两方面: a) 我需要将任何一个客户端(或者套接字)在t1秒内没有响应的情况标记为已死亡。如果read_fd_集合中的套接字在超时值内没有任何内容可读取,则使用select将超时。所以,我如何超时任何一个套接字,它在相当长的一段时间内没有数据读取c-多个select()以监视多个FD_集,c,sockets,select,C,Sockets,Select,我不是网络编程专家。我基本上有两种客户有不同的暂停时间。我应该使用UDP和连接的套接字进行客户机-服务器通信 问题有两方面: a) 我需要将任何一个客户端(或者套接字)在t1秒内没有响应的情况标记为已死亡。如果read_fd_集合中的套接字在超时值内没有任何内容可读取,则使用select将超时。所以,我如何超时任何一个套接字,它在相当长的一段时间内没有数据读取 目前,每当select返回时,我自己都会跟踪哪些套接字正在响应,哪些没有响应。我将t1.tu_秒添加到每个客户机(套接字)的单独运行时
- 目前,每当select返回时,我自己都会跟踪哪些套接字正在响应,哪些没有响应。我将t1.tu_秒添加到每个客户机(套接字)的单独运行时间中。然后,我手动关闭并从FD_设置中排除在(n)*(t1.tu_秒)时间内没有响应的套接字。这是一个足够好的方法吗?
- 我可以为同一循环中的两种客户端使用两个select()吗?如果没有线程,它会导致饥饿吗?在这种情况下,是否建议(甚至要求)使用线程
非常感谢您的帮助 只需一次
select
调用即可轻松解决此问题。对于每个套接字,有两个与超时相关的值:实际超时;以及超时之前的时间量。然后每隔0.1秒(或类似时间)倒计时“直到超时的时间”,当它达到零时,关闭套接字。如果套接字在超时之前接收到通信量,只需将“直到超时的时间”重置为超时值,然后再次开始倒计时。我想到的一个快速解决方案是将套接字按剩余时间排序,直到最近的超时
使用选择
,将超时设置为剩余的最小时间,从集合中移除/关闭/删除超时套接字,然后重复
因此,在伪代码中,它可能如下所示:
C = collection of structs ( socket, timeout, time_remaining := timeout )
while (true) {
sort_the_collection_by_time_remaining
next_timeout = min(time_remaining in C)
select ( sockets in C, next_timeout )
update_all_time_remaining_values
remove_from_C_if_required //if timeout occured
}
这只是一种非常常见的模式的特例,其中选择/轮询循环与计时器集合相关联 您可以使用任务优先级队列,按下一个(绝对)触发时间排序;然后,select timeout始终只是队列前面的绝对时间
- 当选择超时时(在下一次迭代之前,如果您的任务可能需要很长时间才能完成),获取当前时间,将本应已执行的每个任务从队列中拉出,然后执行它
- (某些)任务将需要重新调度,因此请确保在执行此操作时它们可以改变优先级队列
- 读取时,将套接字标记为忙
- 在计时器执行时,将套接字标记为空闲
- 如果它已经处于空闲状态,则意味着自上次计时器到期后未收到任何内容:它已死亡