6 c linux network-programming multicast
当我创建两个udp套接字并将它们绑定到INADDR_ANY和相同的端口号时.但其中一人加入了一个组播组.但是它们都可以从同一个组播组接收数据,即使其中一个套接字没有加入组播组.
内核根本不会根据套接字所属的多播组来过滤传入的多播数据包。如果您不将套接字添加到组中,并且同一系统上的其他套接字是该组的成员,则该套接字仍可能会接收到该组的多播。(我不确定如果多播到达但没有套接字是成员会发生什么。如果您愿意,可以测试。)
请注意,内核实际上确实跟踪组所有权,甚至是每个套接字。它必须这样做,否则就无法正确实现 IGMP 协议的客户端。例如,内核需要回复来自路由器的各种 IGMP 查询(询问主机加入到哪些组),并且当没有更多套接字加入时,它也知道发送离开组消息一个特定的群体。
Linux 内核不跟踪 IGMP 加入的状态。IGMP 是一种路由器协议。向多播组发送 IGMP 加入只是告诉路由器它应该将数据包转发到给定的地址和端口。请注意,路由器必须能够进行 IGMP 通信。
这意味着虽然您曾经setsockopt()加入多播组,但内核不会像您所期望的那样跟踪每个套接字的成员身份。内核只是向路由器发送 IGMP 加入数据包。您可以使用wireshark 或其他工具来验证这一点。
由于内核不跟踪套接字的 IGMP 状态,因此该地址和端口上的传入流量只是内核的“常规”流量。
因此,如果您将两个套接字绑定到相同的地址和端口,然后使用该地址和端口发送 IGMP 加入,则数据包在两个套接字上均可用是预期的行为。
顺便说一句:为什么需要将两个套接字绑定到相同的地址和端口?
更新:根据@Ambroz Bizjak(谢谢)的解释,Linux 内核不跟踪 IGMP 加入的状态是不正确的。确实如此。但如果多个套接字绑定到相同的地址和端口,它不会使用此信息来决定哪些数据包应转发到哪个套接字。