1

I'm writing a TCP server that uses non-blocking sockets and epoll() for I/O multiplexing. I want to detect idle connections so that I can close them. I cannot use setsockopt with RCVTIMEO because sockets don't block. How can we set a timeout on a nonblocking socket? This is related to another question of mine: Time out idle connections in epoll based server If dobuble post please tell me and I will delete this or the other question.

Mihai
  • 509
  • 5
  • 14

1 Answers1

2

Use a timer with your socket. The event loop library you use should provide timers.

Alternatively, you can have one global timer that fires, say, once per minute. In this timer callback you check the last activity time of each client connection and disconnect ones that hasn't been active for a while.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • I'm doing it, I keep a last_active time_t variable associated with each connection, which I update to the current time in the event handler. Before doing that, I check if more than the allowed time has ellapsed since last event and if so I terminate the connection. It's not really what I want because the timeout is only triggered on the first out-of-time event, but if the connection remains inactive, my code doesn't detect it until it becomes "active" again. I'm using epoll directly, I'm not using any event library. – Mihai Aug 10 '18 at 14:41
  • @miguel That is not a timer you described. The timers you use must invoke your callback when it expires. – Maxim Egorushkin Aug 10 '18 at 14:46
  • Mmm... thank you. Any idea on how to do that without an event library like libevent? – Mihai Aug 10 '18 at 14:51
  • 1
    @miguel Use a timeout argument to `epoll`. Track current time. Once enough time passed do dead client detection. I was going to suggest using `libevent`. – Maxim Egorushkin Aug 10 '18 at 14:53
  • Thanks, I'm going to do that. Instead of linearly traversing the set of connections I'm going to use a priority queue to timeout when the next connection should be disconnected as described here https://stackoverflow.com/questions/8544856/is-there-a-library-for-c-that-provides-priority-queues. – Mihai Aug 10 '18 at 15:07
  • 2
    You don't need a priority queue if all the timeout values are the same. New timeouts will always go at the start of the queue, and the one with the nearest timeout-time will always be at the end. – Martin James Aug 10 '18 at 16:17
  • 1
    @miguel With libevent you do not need to do that. Just register a read event for your socket fd along with a timer. libevent internally maintains timers in a min-heap (my contribution to libevent in 2006) and uses the earliest timer expiry as the timeout to `epoll`. – Maxim Egorushkin Aug 10 '18 at 21:32
  • @MaximEgorushkin thanks but I'm trying to write a minimal program with no depencencies, in a future project I will use libevent for sure. – Mihai Aug 12 '18 at 07:00
  • yes but what happens when the connection that would be at the head of the queue terminates? Now you need to know which is the next connection scheduled for timeout. It's the one with the lowest last active timestamp. To know that we need a priority queue and update the position of a connection when an event happens on it – Mihai Aug 12 '18 at 07:21