我不是网络编程专家。我基本上有两种客户,他们有不同的超时时间。我应该使用带有连接套接字的 UDP 来进行客户端-服务器通信。
问题是双重的:
a)无论哪个客户端(或者套接字)在 t1 秒内没有响应,我都需要将其标记为死亡。如果 read_fd_set 中的套接字在超时值内没有任何内容可读取,则使用 select 将会超时。那么,如何使某个相当长一段时间没有数据可读取的套接字超时呢?
b) 主要问题是有两种客户端具有不同的超时时间,t1 和 t2。我该如何处理这个问题?
我已经在网络上漫游多年了!
非常感谢任何帮助。
这只是一个非常常见模式的特例,其中选择/轮询循环与计时器集合相关联。
您可以使用任务优先级队列,按下一个(绝对)触发时间排序;选择超时始终只是队列前面的绝对时间。
那么你的逻辑就很简单了:
我想到的一个快速解决方案是将套接字保留在一个集合中,按剩余时间排序,直到最近的超时。
使用
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
}
只需一次
select
调用即可轻松解决。对于每个套接字都有两个与超时相关的值: 实际超时;以及超时之前的时间量。然后每隔 0.1 秒(或类似时间)倒计时“超时时间”,当达到零时关闭套接字。如果套接字在超时之前收到流量,只需将“超时前的时间”重置为超时值,然后再次开始递减计数。