How to flush UDP socket input buffer in C?

How to clear input buffer (if such a thing exists at all) UDP Socket in C?

I am working on an embedded Linux environment and using C I am creating my own application. There are several such embedded machines in one network, and when an event occurs on one of them (let's call it WHISTLE-BLOWER), WHISTLE-BLOWER must send a network message to the broadcast address of the network so that all machines on the network (including WHISTLE-BLOWER) know about event and performs some actions in accordance with it. I am using a 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 with this code:

 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 

Principle of operation:

 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: packets / messages / UDP broadcasts sent to an already bound socket, whoose parent thread - delivery sleep time; somehow queued / buffered and delivered the next time “recvfrom” is called on the specified socket.

I want these UDP transmissions to be ignored, so I thought about flushing the receive buffer (obviously not the one I provide as a parameter to the recvfrom method) if it exists before recvfrom is called. How can i do this? or which way should i stick to?

+2
source share
2 answers

Please note that the term “flushing” applies only to the outlet. A flash empties the buffer and ensures that everything in it is sent to its destination. As for the input buffer, the data is already at the destination. Input buffers can be read or flushed, but not flushed.

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

+3
source

The socket has a single receive buffer inside the TCP / IP stack. These are, in fact, FIFOs of received datagrams. TCP and UDP handle this queue differently. When you call recv(2) on a UDP socket, you remove one datagram from this buffer. TCP organizes datagrams into a stream of bytes according to sequence numbers. When the transfer buffer is full, the datagram is deleted by the stack. TCP tries to resend in this case. UDP does not. There is no explicit "flash" function for the receive buffer, and then reading the socket or closing it.

Edit:

You have an inherent race condition in your application, and it looks like you are trying to solve a problem with the wrong tool (TCP / IP stack). What I think you need to do is define a clean state machine for the application. Manage events that make sense in the current state, ignore events that do not.

Another thing to look out for is to use multicast instead of broadcasting. This is a bit more active, but you will have more control over your “subscriptions” by combining / listing multicast groups.

+1
source

All Articles