【问题标题】:What happens to select() when socket is set to handle timeout当套接字设置为处理超时时 select() 会发生什么
【发布时间】:2019-09-02 11:19:15
【问题描述】:

根据recv() 的手册页,如果使用setsockopt(SO_RCVTIMEO) 为接收设置了超时,则errno 设置为EAGAINEWOULDBLOCK

我的问题是如果多个这样的套接字与select() 一起使用会发生什么。如果其中一个套接字由于不活动而超时,将选择返回。 select() 将返回什么。

我正在尝试实现一个具有超时检测功能的 tftp 服务器。一种方法是使用select() 的超时,但是我必须为每个套接字使用不同的超时值,并不断将计时器更新为最小值,然后再做一些杂耍......等等。等等......感觉就像很多不必要的工作。

PS:tftp 服务器是一个并发服务器,使用 I/O 多路复用处理多个客户端。

【问题讨论】:

  • 改为使套接字非阻塞。
  • 并使用警报实现超时??还有什么办法?
  • 不,你会使用 select 超时。
  • 不,使用警报是个坏主意。这就是为什么我建议选择超时。您需要为每个套接字缓冲数据,以便为每个套接字设置一个 结构
  • 将结构体或指向它们的指针保存在队列中。具有最近超时的结构将始终位于头部,因此头部超时。在尾部添加新的超时。

标签: tcp udp ip tftp


【解决方案1】:

select() 的 timeout 参数决定了 select() 调用本身在调用返回之前等待某事发生的最长时间,而不是单个套接字在返回超时错误之前等待多长时间。

如果您在一段时间内没有收到客户的来信,听起来您想要声明某种错误情况。使用 UDP,您必须自己跟踪。对于每个客户,请记录您上次收到的消息。将 select() 放入一个超时时间为 1 秒的循环中,然后每次返回时检查当前时间与您上次从每个客户端听到的时间之间的差异。当该差异超过您想要的任何阈值时,您就会遇到错误情况。

【讨论】:

  • 这就是为什么我想为每个套接字设置超时参数而不是select()。我的理解是,如果我将单个套接字设置为超时,然后调用select(),如果套接字超时,我将简单地使用套接字 fd 从 select 返回,并尝试读取套接字。我想读取会因 EAGAIN 而失败,这是我的错误情况。
  • UDP 套接字不会超时。只有启用 keepalive,TCP 套接字才会超时。
猜你喜欢
  • 1970-01-01
  • 2017-01-31
  • 2021-08-22
  • 2013-04-06
  • 2013-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多