2
votes

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
Since you're concerned about lost packets, why not use TCP? My understanding was that UDP is best for "pitch and forget" situations, i.e. where a bit of packet loss is acceptable and where ordering is not critical. In cases where it is not acceptable to lose any packets and packets must be received "in order", TCP handles tracking, acknowledgment, retries, and packet ordering.Assad Ebrahim

2 Answers

1
votes

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.

0
votes

select() will block the same way recvmsg() blocks. It is a substitute with a timeout. You can also the SO_RCVTIMEO option to set a read timeout, which is simpler if supported by your platform.