【发布时间】:2018-08-09 09:16:49
【问题描述】:
我正在用 c 语言编写一个 tcp 服务器,它使用 epoll() i/o 多路复用来管理并发连接。我想使空闲时间超过允许时间的连接超时。
到目前为止,我保留了一个与每个连接关联的 last_active time_t 变量,我将其更新为事件处理程序中的当前时间。在此之前,我检查自上次事件以来是否超过了允许的时间,如果是,我终止连接。
到目前为止一切都很好,但这并不是我真正想要的,因为超时仅在第一个超时事件上触发,但如果连接保持非活动状态,我的代码在它变为“活动”之前不会检测到它再次。
我在基于 select() 的服务器中看到的方法是在事件循环的每次迭代期间线性遍历兴趣集并清除那里的非活动连接。这在 select 中不是问题,因为无论如何您都必须执行此遍历,但我使用 epoll() 正是为了避免必须这样做。如果我这样做,epoll 并不比 select 好。
我还研究了套接字选项,我发现最接近的是 SO_RCVTIMEO,如果它等待超过指定时间,它会使 read()/recv() 返回错误。但是由于我正在使用 i/o 多路复用并且套接字处于非阻塞模式,因此这不会产生问题,因为套接字不会阻塞。
我将不胜感激有关如何解决此问题的任何见解。非常感谢。
【问题讨论】:
-
如果您使用
SO_RCVTIMEO,当连接超时时您会收到epoll通知吗?您对epoll使用了哪些选项?您使用的是EPOLLHUP还是EPOLLRDHUP?见stackoverflow.com/questions/27175281/epollrdhup-not-reliable -
@AndrewHenle 我已经在客户端套接字上打开了
SO_RCVTIMEO,我还设置了 epoll 来监听EPOLLHUP和EPOLLRDHUP。在通过 netcat 打开连接并等待指定超时空闲后,不会触发 epoll 事件并且 read() 调用不会返回错误EAGAIN或EWOULDBLOCK,即使我在超时后发送了一些数据。看起来SO_RCVTIMEO对非阻塞套接字(?)没有影响。
标签: c sockets network-programming nonblocking epoll