I'm writing a UDP server/client program in which the server send packets to client through a single port with a fixed window size, and the client will send ack packet back for each packet received. Now I want the server to handle lost packets situation. By some googling, it seems I should use ALARM
or SELECT
. I certainly don't want to send one packet, wait for ack or timeout, then send another, but SELECT
will block the calling function during the timeout, so I think it's not good. ALARM
isn't good either since one program can only have one ALARM
. So is there any way to allow me to keep tracking timeout for multiple packets server sends?
2 Answers
The following is what comes to my mind first.
Open socket to listen on in non-blocking mode. Non-blocking is key. If select says something is there, but events align just right, it may be a false alarm handled elsewhere and blocking on something that is not coming is trouble.
For each packet sent keep a linked list of sorted by ascending time out times.
As responses are received remove from linked list.
Use select to wait for the next incoming packet with some reasonable time out. I tend to use a maximum of a few seconds even if it looks like a longer time out is reasonable to cover any rare "just in case" situations. What you are blocking on here is incoming packets, but NOT beyond the next time out.
Once the select returns, if requests are available then accept() and process the requests.
Before iterating the loop handle any new time outs, adjusting the linked list as appropriate.
A quick web search turned up more details at http://www.lowtek.com/sockets/select.html.