套接字未加入多播组,但可以接收数据.

6 c linux network-programming multicast

当我创建两个udp套接字并将它们绑定到INADDR_ANY和相同的端口号时.但其中一人加入了一个组播组.但是它们都可以从同一个组播组接收数据,即使其中一个套接字没有加入组播组.

Amb*_*jak 5

内核根本不会根据套接字所属的多播组来过滤传入的多播数据包。如果您不将套接字添加到组中,并且同一系统上的其他套接字是该组的成员,则该套接字仍可能会接收到该组的多播。(我不确定如果多播到达但没有套接字是成员会发生什么。如果您愿意,可以测试。)

请注意,内核实际上确实跟踪组所有权,甚至是每个套接字。它必须这样做,否则就无法正确实现 IGMP 协议的客户端。例如,内核需要回复来自路由器的各种 IGMP 查询(询问主机加入到哪些组),并且当没有更多套接字加入时,它也知道发送离开组消息一个特定的群体。


hek*_*mgl 4

Linux 内核不跟踪 IGMP 加入的状态。IGMP 是一种路由器协议。向多播组发送 IGMP 加入只是告诉路由器它应该将数据包转发到给定的地址和端口。请注意,路由器必须能够进行 IGMP 通信。

这意味着虽然您曾经setsockopt()加入多播组,但内核不会像您所期望的那样跟踪每个套接字的成员身份。内核只是向路由器发送 IGMP 加入数据包。您可以使用wireshark 或其他工具来验证这一点。

由于内核不跟踪套接字的 IGMP 状态,因此该地址和端口上的传入流量只是内核的“常规”流量。

因此,如果您将两个套接字绑定到相同的地址和端口,然后使用该地址和端口发送 IGMP 加入,则数据包在两个套接字上均可用是预期的行为。

顺便说一句:为什么需要将两个套接字绑定到相同的地址和端口?

更新:根据@Ambroz Bizjak(谢谢)的解释,Linux 内核不跟踪 IGMP 加入的状态是不正确的。确实如此。但如果多个套接字绑定到相同的地址和端口,它不会使用此信息来决定哪些数据包应转发到哪个套接字。

  • 这是不正确的。内核确实跟踪每个套接字的 IGMP 加入状态。它必须这样做,这样它才能正确地实现IGMP 协议(​​例如响应IGMP 通用查询和IGMP 特定组查询)。然而,它*不*使用此信息来过滤传入的数据包。 (3认同)
  • 您可能会问,为什么它需要跟踪*每个套接字*。这样,当加入特定组的最后一个套接字关闭时,它可以发送 IGMP 离开组消息,并停止回复对该组的查询。 (2认同)