0

我正在使用 C 语言开发一个应用程序,该应用程序在一个套接字上侦听多个多播组。我正在禁用套接字选项:IP_MULTICAST_ALL。套接字正在接收来自 20 个不同的多播组的流量。此流量以突发方式到达套接字。其中一个频道每秒只发布一条消息,这里没有发现任何问题。

我也有一个可靠的协议用于这个多播提要。如果一个侦听器错过了一条消息,那么协议会尝试通过消息与源对话来恢复该消息,然后像往常一样通过相同的通道执行重传。

当有消息突发到达套接字时,就会出现问题,然后 RUDP 协议会强制重新传输这些消息。消息到达没有问题,但如果消息突发组停止重新传输新数据,因为它们没有更多的流量要发送,有时(很容易重现它)套接字不会从这些中读取那些待处理的传入消息如果周期性消息从不同的组(具有微小流量、微小和周期性流量的组)到达,则分组。到目前为止的情况是,之前发送了许多传入消息,等待应用程序读取(不再通过该组发送数据),来自另一个组的周期性消息,该组定期发送一些消息。

我在这里看到的是,应用程序从定期发送一些消息的组中读取一条消息,然后从其他组(突发组)中读取一批消息。套接字配置为非阻塞,每次从套接字读取一批消息时我都会得到 EAGAIN errno,然后没有更多数据要读取,直到套接字从周期性组获得新消息,然后读取此消息以及来自其他组的一批其他未决消息(应用程序仅从一个套接字读取)。我确保其他组不会产生更多数据,因为我测试了停止其他进程以发送更多数据。因此,这些组上的所有待处理消息都已发送。

最令人惊讶的事实是,如果我阻止写入周期性组的进程发送更多消息,那么侦听器套接字会神奇地从之前发布消息突发的组中获取所有挂起的流量。就像周期性组的流量以某种方式停止处理来自不发布新数据但缓冲区充足的组的流量。

起初我以为它与IGMP或轮询机制有关(我的应用程序可以执行主动等待或阻塞等待)。阻塞等待是通过非阻塞套接字实现的,但如果 errno 设置为 EAGAIN,则应用程序会等待轮询以获取新消息。在这两种情况下,我都会得到相同的行为。我认为这不是 IGMP,因为 IGMP_SNOOPING 在交换机中处于关闭状态,并且因为我使用一台计算机环回来重现相同的行为,以进行所有这些进程之间的通信。

我还使用内核绕过技术(不使用内核 API 来处理网络)重现了这种行为,因此它似乎与 TCP/IP 堆栈无关。使用内核绕过技术,我有相同的范式:一个消息接口从所有组中获取所有流量。在这种情况下,所有进程都使用这种机制进行通信,而不是几个 TCP/IP 和几个内核旁路。该模型是同质的。

当我从多个组接收实时流量时,我只收到一批消息(但不是全部),但如果我停止来自不同多播组的定期流量,我怎么会收到所有待处理的流量?这个周期性的流量组每秒只有一条消息。突发组不再发布,因为所有消息都已发布。

请问,有人知道我接下来应该检查什么吗?

4

0 回答 0