Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making recvfrom() function non-blocking

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.

like image 241
Ayse Avatar asked Apr 11 '13 04:04

Ayse


People also ask

Is Recvfrom a blocking call?

By default, Recvfrom() is blocking: when a process issues a Recvfrom() that cannot be completed immediately (because there is no packet), the process is put to sleep waiting for a packet to arrive at the socket. Therefore, a call to Recvfrom() will return immediately only if a packet is available on the socket.

How do I make a UDP socket non-blocking?

To mark a socket as non-blocking, we use the fcntl system call. Here's an example: int flags = guard(fcntl(socket_fd, F_GETFL), "could not get file flags"); guard(fcntl(socket_fd, F_SETFL, flags | O_NONBLOCK), "could not set file flags"); Here's a complete example.

What is the use of socket Recvfrom () method?

The recvfrom() function receives data on a socket named by descriptor socket and stores it in a buffer. The recvfrom() function applies to any datagram socket, whether connected or unconnected. The socket descriptor. The pointer to the buffer that receives the data.


1 Answers

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).

like image 133
alk Avatar answered Sep 21 '22 22:09

alk