20

I am working on a UDP server/client application.

For finding out if any of the client is down, the server sends a handshake message to the client. Then, the server waits for the response of client to send some data to assure that the client is active. For this the server blocks in call to recvfrom() unless the client replies back, but if the client is down, the server blocks infinitely in call to recvfrom().

I want to implement such a functionality on my server so that it waits in the call to recvfrom() for a specific time (say 2 secs). If no data was received from the client within 2 seconds, the client is considered to be dead and recvfrom() returns.

Is there any way to do it? I searched internet but found solutions like setting MSG_DONTWAIT flag that returns immediately when no data received, but in my case, I don't want recvfrom() to return immediately but wait for data for a specific duration of time, and when no data received for that specific duration, the recvfrom() function should return.

alk
  • 69,737
  • 10
  • 105
  • 255
Ayse
  • 2,676
  • 10
  • 36
  • 61
  • 1
    Ok you wants to implement reliable service. you can set [recvfrom() function](http://publib.boulder.ibm.com/infocenter/zos/v1r11/index.jsp?topic=/com.ibm.zos.r11.hala001/rcvf.htm) in blocking mode, using [fcntl() or ioctl() function](http://publib.boulder.ibm.com/infocenter/zos/v1r11/index.jsp?topic=/com.ibm.zos.r11.hala001/rcvf.htm). Also read this [UDP reliable data service implementation](http://stackoverflow.com/questions/8353970/udp-reliable-data-service-implementation) – Grijesh Chauhan Apr 11 '13 at 05:46
  • 1
    checkout **[c - Set timeout for winsock recvfrom - Stack Overflow](http://stackoverflow.com/questions/1824465/set-timeout-for-winsock-recvfrom)** – Koushik Shetty Apr 11 '13 at 05:49
  • 1
    also [check out](http://msdn.microsoft.com/en-us/library/windows/desktop/ms740120%28v=vs.85%29.aspx) .it gives you clear explanation in **WSARecv()** (has blocking rules for function). – Koushik Shetty Apr 11 '13 at 05:52
  • 1
    @GrijeshChauhan It's ioctlsocket, for Windows. Somewhat lame and non-Unix-like, but sockets aren't treated as regular files... – autistic Apr 11 '13 at 05:57
  • @modifiablelvalue ok I didn't notice `window` tag. Anyway @ Ayesha There must be some similar way in windows also. Sorry I can't help on this more...Good Luck – Grijesh Chauhan Apr 11 '13 at 06:01
  • 1
    What about using `select()` after having written to the client to be tested. `select()` takes on optional time-out. – alk Apr 11 '13 at 06:17
  • Thank you everyone for all the helpful posts :) – Ayse Apr 11 '13 at 06:44

1 Answers1

25

The easiest way would be to use setsockopt() to set a receive time-out for the socket in question.

SO_RCVTIMEO is used for this.

If a time-out has been set for a socket passed to recvfrom(), the function returns after this time-out if no data had been received.

For instance, to set a 10 μs read time-out (add error-checking on the value returned by setsockopt() as necessary):

#include <sys/types.h> 
#include <sys/socket.h>

...

struct timeval read_timeout;
read_timeout.tv_sec = 0;
read_timeout.tv_usec = 10;
setsockopt(socketfd, SOL_SOCKET, SO_RCVTIMEO, &read_timeout, sizeof read_timeout);

For details on Windows please see here, and on Linux see here and/or here (POSIX).

alk
  • 69,737
  • 10
  • 105
  • 255
  • 13
    or use `select()` to wait for the socket to enter a readable state within a timeout, THEN call `recvfrom()` only when the socket is actually readable indicating data is available for reading. – Remy Lebeau Apr 11 '13 at 19:46
  • I second the use of `select`. You get far better control, and its easier to upscale to handling multiple sockets. – Chris Becke Mar 01 '17 at 05:55
  • Isn't the ms docs stating that SO_RCVTIMEO should be given a DWORD? Why are you giving it a timeval struct – xXTurner Apr 09 '23 at 19:42