Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c-多个select()以监视多个FD_集_C_Sockets_Select - Fatal编程技术网

c-多个select()以监视多个FD_集

c-多个select()以监视多个FD_集,c,sockets,select,C,Sockets,Select,我不是网络编程专家。我基本上有两种客户有不同的暂停时间。我应该使用UDP和连接的套接字进行客户机-服务器通信 问题有两方面: a) 我需要将任何一个客户端(或者套接字)在t1秒内没有响应的情况标记为已死亡。如果read_fd_集合中的套接字在超时值内没有任何内容可读取,则使用select将超时。所以,我如何超时任何一个套接字,它在相当长的一段时间内没有数据读取 目前,每当select返回时,我自己都会跟踪哪些套接字正在响应,哪些没有响应。我将t1.tu_秒添加到每个客户机(套接字)的单独运行时

我不是网络编程专家。我基本上有两种客户有不同的暂停时间。我应该使用UDP和连接的套接字进行客户机-服务器通信

问题有两方面:

a) 我需要将任何一个客户端(或者套接字)在t1秒内没有响应的情况标记为已死亡。如果read_fd_集合中的套接字在超时值内没有任何内容可读取,则使用select将超时。所以,我如何超时任何一个套接字,它在相当长的一段时间内没有数据读取

  • 目前,每当select返回时,我自己都会跟踪哪些套接字正在响应,哪些没有响应。我将t1.tu_秒添加到每个客户机(套接字)的单独运行时间中。然后,我手动关闭并从FD_设置中排除在(n)*(t1.tu_秒)时间内没有响应的套接字。这是一个足够好的方法吗?
b) 主要的问题是有两种类型的客户端具有不同的超时,t1和t2。我该怎么处理

  • 我可以为同一循环中的两种客户端使用两个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始终只是队列前面的绝对时间

  • 当选择超时时(在下一次迭代之前,如果您的任务可能需要很长时间才能完成),获取当前时间,将本应已执行的每个任务从队列中拉出,然后执行它
  • (某些)任务将需要重新调度,因此请确保在执行此操作时它们可以改变优先级队列
那么你的逻辑就微不足道了:

  • 读取时,将套接字标记为忙
  • 在计时器执行时,将套接字标记为空闲
    • 如果它已经处于空闲状态,则意味着自上次计时器到期后未收到任何内容:它已死亡

请重新格式化您的问题(即段落分隔符等),使其真正可读?哦!我确实做了休息,但我不知道网站需要什么格式。显然,简单的换行还不够好。让我做必要的操作。您不能同时阻止两个select()调用。要么将所有fd放入一个fd_集中,要么使用两个fd_集中,并交替调用select。(IIRC后一种技术有时用于区分快FD和慢FD)只是一个快速优化:更新响应的套接字就足够了,列表的标题(当然,这只适用于大量套接字)非常感谢您的响应。这基本上就是我目前正在做的事情:每次select返回时,我自己都要跟踪有响应和无响应的套接字。我在想,我自己不必保持长取和短取的区别。无论如何,谢谢!:)