繁体   English   中英

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

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

如何在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广播,其父线程在传递时处于休眠状态; 在所述套接字上的下一个“ recvfrom”调用中以某种方式排队/缓冲并传递。

我希望忽略那些UDP广播,因此我在考虑在调用recvfrom之前刷新接收缓冲区(显然不是我作为recvfrom方法的参数提供的缓冲区)。 我怎样才能做到这一点? 还是我应该走什么路?

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

如果只想确保已读取输入缓冲区中的所有内容,那么您正在寻找的是无阻塞读取操作。 如果您尝试使用它而没有输入,它将返回一个错误。

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

编辑:

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

要看的另一件事是使用多播而不是广播。 它涉及的更多,但是通过加入/离开多播组,您将对“订阅”有更多的控制。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM