Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to flush Input Buffer of an UDP Socket in C?

Tags:

How to flush Input Buffer (if such thing exists at all) of an UDP Socket in C ?

I'm working on an embedded Linux environment and using C to create some native application. There are several of these embedded machines on the same network, and when an event occurs on one of them (lets call it the WHISTLE-BLOWER), WHISTLE-BLOWER should send a network message to the network broadcast address, so that all machines on the network (including the WHISTLE-BLOWER) knows about the event and executes some actions according to it. I'm using UDP socket by the way...

Here's the pseudo-code for it:

main
{
    startNetworkListenerThread( networkListenerFunction );

    while( not received any SIGTERM or such )
    {
        localEventInfo = checkIfTheLocalEventOccured();
        broadcastOnNetwork( localEventInfo );
    }
}

networkListenerFunction
{
    bindSocket;

    while( not SIGTERM )
    {
// THIS IS WHERE I WANT TO FLUSH THE RECV BUFFER...
        recv_data = recvfrom( socket );
        if( validate recv data )
        {
            startExecuteLocalAction;
            sleep( 5 );
            stopExecuteLocalAction;
        }
    }
}

The way I expect and want to work this code is:

1. LOCAL_EVENT occured
2. Broadcasted LOCAL_EVENT_INFO on network
3. All machines received EVENT_INFO, including the original broadcaster
4. All machines started executing the local action, including the original broadcaster
5. All machines' network listener(thread)s are sleeping
6. Another LOCAL_EVENT2 occured
7. Since all machines' listener are sleeping, LOCAL_EVENT2 is ignored
8. All machines' network listener(thread)s are now active again
9. GO BACK TO 1 / RESTART CYCLE
RESULT = TOTAL 2 EVENTS, 1 IGNORED

The way it actually works is:

1. LOCAL_EVENT occured
2. Broadcasted LOCAL_EVENT_INFO on network
3. All machines received EVENT_INFO, including the original broadcaster
4. All machines started executing the local action, including the original broadcaster
5. All machines' network listener(thread)s are sleeping
6. Another LOCAL_EVENT2 occured
7. Eventhough all machines' listener are sleeping; LOCAL_EVENT2 is queued  SOMEHOW
8. All machines' network listener(thread)s are now active again
9. All machines received EVENT_INFO2 and executed local actions again, slept and reactivated
10. GO BACK TO 1 / RESTART CYCLE
RESULT = TOTAL 2 EVENTS, 0 IGNORED

tl,dr: The packets/messages/UDP Broadcasts sent to an already binded socket, whoose parent thread is sleeping at the delivery-moment; are somehow queued/buffered and delivered at the next 'recvfrom' call on the said socket.

I want those UDP broadcasts to be ignored so I was thinking of flushing the receive buffer (obviously not the one i'm giving as parameter to the recvfrom method) if it exists before calling recvfrom. How can I do that? or what path should I follow?

like image 541
Cihan Keser Avatar asked Feb 19 '10 21:02

Cihan Keser


1 Answers

Please note that the notion of "flushing" only applies to output. A flush empties the buffer and ensures everything in it was sent to its destination. Regarding an input buffer, the data is already at its destination. Input buffers can be read from or cleared out, but not "flushed".

If you just want to make sure you have read everything in the input buffer, what you are looking for is a non-blocking read operation. If you try it and there's no input, it should return an error.

like image 153
bta Avatar answered Sep 26 '22 10:09

bta