如何在C中刷新UDP套接字的输入缓冲区?

如何在C中清除UDP套接字的输入缓冲区(如果存在这样的东西)?

我正在使用嵌入式Linux环境并使用C来创建一些本机应用程序。 这些嵌入式计算机中有几台位于同一网络上,当其中一台事件发生时(让我们称之为WHISTLE-BLOWER),WHISTLE-BLOWER应该向网络广播地址发送网络消息,以便所有机器都在网络(包括WHISTLE-BLOWER)知道事件并根据它执行一些操作。 我顺便使用UDP套接字……

这是它的伪代码:

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; } } } 

期望并希望使用此代码的方式是:

 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 

它的实际工作方式是:

 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:发送到已经绑定的套接字的数据包/消息/ UDP广播,父母线程在交付时刻正在hibernate; 以某种方式排队/缓冲并在所述套接字上的下一次“recvfrom”调用时传送。

我希望忽略那些UDP广播,所以我想要在调用recvfrom之前刷新接收缓冲区(显然不是我给recvfrom方法作为参数的那个)。 我怎样才能做到这一点? 或者我应该遵循什么样的路径?

请注意,“冲洗”的概念仅适用于输出。 刷新清空缓冲区并确保其中的所有内容都已发送到目标。 关于输入缓冲区,数据已经在其目的地。 可以读取或清除输入缓冲区,但不能“刷新”。

如果您只是想确保已经读取了输入缓冲区中的所有内容,那么您要查找的是非阻塞读取操作。 如果您尝试并且没有输入,则应该返回错误。

套接字在TCP / IP堆栈中有一个接收缓冲区 。 它本质上是收到的数据报的FIFO。 TCP和UDP处理该队列的方式不同。 在UDP套接字上调用recv(2)时,将该缓冲区中的单个数据报出列。 TCP根据序列号将数据报排列成字节流。 当接收缓冲区溢出时,堆栈会丢弃数据报。 在这种情况下,TCP尝试重新发送。 UDP没有。 除了读取套接字或关闭套接字之外,接收缓冲区没有明确的“刷新”function。

编辑:

您的应用程序中存在固有的竞争条件,看起来您正试图使用​​错误的工具(TCP / IP堆栈)来解决它。 我认为你应该做的是为应用程序定义一个干净的状态机。 处理当前状态下有意义的事件,忽略不事件的事件。

另一个需要注意的是使用多播而不是广播。 它涉及的有点多,但您可以通过加入/离开多播组来更好地控制“订阅”。