【问题标题】:c - Multiple select()s to monitor multiple FD_SETsc - 多个 select()s 来监控多个 FD_SET
【发布时间】:2012-09-26 10:56:55
【问题描述】:

我不是网络编程方面的专家。我基本上有两种客户,他们有不同的超时时间。我应该使用带有连接套接字的 UDP 进行客户端-服务器通信。

问题是双重的:

a) 无论哪个客户端(或者套接字)在 t1 秒内没有响应,我都需要将其标记为已死亡。如果 read_fd_set 中的任何套接字都没有在超时值内读取任何内容,则使用 select 将超时。那么,如何让任何一个在相当长一段时间内没有数据读取的套接字超时?

  • 目前,每当 select 返回时,我自己都会跟踪哪些套接字正在响应,哪些没有。我将 t1.tu_sec 添加到每个客户端(套接字)的单独经过时间。然后,我手动关闭并从 FD_SET 中排除在 (n) * (t1.tu_sec) 时间内没有响应的套接字。这是一个足够好的方法吗?

b) 主要问题是有两种客户端有不同的超时时间,t1 和 t2。我该如何处理?

  • 我可以在同一个循环中为两种客户端设置两个 select() 吗?没有线程会导致饥饿吗?在这种情况下是否建议(甚至需要)使用线程?

我已经在网上漫游很久了!

非常感谢任何帮助。

【问题讨论】:

  • 能否请您重新格式化您的问题(即分段符等),以便它真正可读?
  • 哦!我确实设置了中断,但我不知道网站需要的格式。显然简单的换行符是不够的。让我做必要的事情。
  • 您不能同时阻止两个 select() 调用。要么将所有 fd 放入一个 fd_set,要么使用两个 fd_set,然后交替调用它们。 (IIRC 后一种技术有时用于将 fastslow fds 分开)

标签: c sockets select


【解决方案1】:

这只是一个非常常见模式的特例,其中选择/轮询循环与计时器集合相关联。

您可以使用任务的优先级队列,在下一个(绝对)触发时间排序;选择超时始终是队列前面的绝对时间。

  • 当 select 超时时(就在下一次迭代之前,如果您的任务可能需要很长时间才能完成),获取当前时间,将所有应该已经执行的任务从队列中拉出并执行
  • (某些)任务需要重新安排,因此请确保在您执行此操作时它们可以改变优先级队列

那么你的逻辑很简单:

  • 读取时,将套接字标记为忙
  • 在定时器执行时,标记套接字空闲
    • 如果它已经空闲,这意味着自上次计时器到期后没有收到任何东西:它已经死了

【讨论】:

    【解决方案2】:

    我想到的一个快速解决方案是将集合中的套接字按剩余时间排序,直到最近的超时。

    使用select,将超时设置为剩余的最短时间,从集合中移除/关闭/删除超时套接字,然后重复。

    因此,在伪代码中它可能如下所示:

    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
    }
    

    【讨论】:

    • 只是一个快速优化:更新响应的套接字和列表的头部就足够了(当然这只对大量套接字有意义)
    【解决方案3】:

    只需一个select 调用即可轻松解决。对于每个套接字都有两个与超时相关的值:实际超时;以及超时前的时间。然后每 0.1 秒(或类似时间)倒计时“超时时间”,当它达到零时关闭套接字。如果套接字在超时之前接收到流量,只需将“超时前的时间”重置为超时值并再次开始向下计数。

    【讨论】:

    • 非常感谢您的回复。这基本上就是我目前正在做的事情:每次选择返回时自己跟踪响应和非响应套接字。我正在考虑不必自己保持长期和短期插座之间的区别。无论如何谢谢! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 2015-06-04
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多