我希望有某种服务器接收事件(即使用套接字),并且每个事件都有不同的ID(即dst端口号)。
有没有办法从我看到特定ID的第一个数据包开始,我开始某种超时(即1ms),如果在那个时间没有接收到具有相同ID的其他信息,则触发事件,但如果收到某些内容,超时将重置为1ms。
我已经看到使用signals
和SIGALARM
信号可以完成类似的事情。但是,我想保留多个"计时器"对于每个不同的ID。
答案 0 :(得分:2)
听起来像select
的工作。当您使用套接字时,您有一个客户端的套接字描述符(可能每个客户端一个,但只要您有一个,它可以工作)。因此,您要么等待数据包到达其中一个套接字,要么等到超时发生。这正是select
所做的。
因此,当您收到消息时计算每个客户端的到期时间,然后在主循环中,只需计算最快到期的超时,并将其作为timeout
参数提供给select.select
(将所有套接字描述符作为rlist
参数)。然后,当新的数据包/消息到达或最早的超时到期时,您会被唤醒。如果是新数据包,则处理数据包并将该提供程序的超时重置为1ms;否则,你在超时到期时做你做的任何事情。
然后计算下一次到期超时。冲洗。泡沫。重复。
这样的事情:
now = time.time()
timeout = min([(client.expiration - now) for client in clients_list])
rrdy, wrdy, xrdy = select.select([client.sock for client in clients_list], [], [], timeout)
if not rrdy:
# Timeout
now = time.time()
for client in clients_list:
if client.expiration < now:
process_timeout(client)
else:
# Process incoming messages
for rsock in rrdy:
process_message(rsock.recv(4096))
client.expiration = time.time() + .001
答案 1 :(得分:1)
请参阅sched
内置模块,该模块具有调度程序。
您可以构造一个新的调度程序实例,然后使用scheduler.enter
来安排在延迟后调用的函数;如果您在时间限制内收到消息,则可以使用scheduler.cancel(event)
从队列中删除其事件;您可以使用scheduler.run()
在另一个线程中运行调度程序,或者可以在具有超时的选择多路复用线程中使用scheduler.run(blocking=False)
。