IP_DROP_MEMBERSHIP行为不一致

时间:2018-10-26 04:33:56

标签: c networking network-programming udp multicast

我有一个用例,其中我使用IP_ADD_MEMBERSHIP加入成员资格,一段时间后我必须达到IP_DROP_MEMBERSHIP(在drop seq id为1之前),然后再次使用IP_ADD_MEMBERSHIP加入成员(对于同一多播组)。我注意到我正在获取下一个数据包(seqid = 2),我认为这不应该发生,因为据我的理解,IP_DROP_MEMBERSHIP应该停止接收udp数据包并刷新它正在使用的套接字,并且一旦我加入,它应该是最新的数据包,并且此行为不一致,有时我只会得到最新的数据包。

请注意,我不想关闭插座。继续使用现有的。

请帮助。我正在使用Centos 7.4

1 个答案:

答案 0 :(得分:0)

尝试将IP_MULTICAST_ALL设置为0。默认值为1。

说明:使用IP_MULTICAST_ALL 0,您的操作系统会将传入的UDP数据包过滤到当前加入的组中,这正是您在说明中所期望的。

但这不是Linux上的默认行为。

默认值(IP_MULTICAST_ALL = 1)是接收进入您的套接字的任何 UDP数据包。绑定到0.0.0.0时,这将是计算机为该端口接收的所有UDP数据包(多播和单播),无论是否加入任何多播组。这意味着您将看到加入和离开多播组与计算机发送的实际IGMP消息之间的差异的所有工件,并且还将看到本地网络中所有路由器和交换机的所有工件和错误。例如,当您离开多播组时,您的OS可能决定根本不发送相应的IGMP消息,例如,因为某个其他套接字也在侦听此多播地址,或者因为OS决定延迟离开。完全允许。

顺便说一句,当您在Linux上绑定到多播地址时,它仅具有过滤功能,而根本没有绑定功能。这样,无论您是否也加入了其他多播组,您都将仅收到针对该特定多播IP的UDP数据包。

关于“刷新”套接字:套接字后面的数据包队列完全超出了您的应用程序范围。您不能影响队列状态或行为(除了是否从队列中读取消息),也不能期望任何特定的行为。

在实践中,我建议: -绑定到0.0.0.0。 -适当地加入和离开多播组。 -检查收到的每个UDP数据包的目标地址,并自己进行过滤。使用IP_PKTINFO获取每个数据包的目标地址。 -不要完全依赖具有明显和确定性组播路由行为的路由器和交换机。他们中的大多数人都有几分钟的超时时间,无法离开多播组。这意味着即使您离开了多播组(即使您没有加入),您也可能会在几分钟内继续接收多播流量。这会掩盖代码中的错误,并在尝试调试时会引起头痛。

这样,您将不必依赖任何依赖于操作系统的行为,并且可以完全控制收到的内容和没有收到的内容。