使用同一个套接字发送和接收UDP组播数据包

3
我找不到可行的示例,所以我要发布一个问题(让我们看看是否可以将其简化为MVP代码示例)。因此,我需要执行mdns查询,可以使用两个套接字(一个用于发送/第二个用于接收),但是到目前为止,我尚未能够使其与单个套接字配合使用。
因此,我执行的步骤如下:
1. 枚举主机上的所有接口地址。然后对于每个主机: 2. 创建非阻塞UDP套接字。 3. bind() 到接口地址:5353或组播组地址(这两个中的任何一个会导致读取或写入失败)。 4. 将IP_MULTICAST_IF设置为本地接口。 5. 加入多播组的IP_ADD_MEMBERSHIP。 6. 将套接字添加到kqueue的读/写集合中。
因此,根据我在第2步中执行的操作,要么读取失败,要么写入失败:
1. 如果我将套接字绑定到多播组,则会从kqueue获得读取通知并可以读取数据包,但当我从kqueue获取写入通知并尝试写入时,它会失败,并显示errno 49。 2. 如果我将套接字绑定到接口地址,则可以发送数据包,但从未收到来自kqueue的读取通知。
那么我需要绑定到哪个地址呢?另外,由于IP_ADD_MEMBERSHIP参数ip_mreq具有接口字段,我真的需要IP_MULTICAST_IF吗?
1个回答

5
如果您在特定接口地址上绑定(至少在Linux上),则无法接收组播。如果您绑定到多播地址,则无法发送。

您需要做的是绑定到INADDR_ANY,然后在设置IP_ADD_MEMBERSHIP选项时,设置您要接收多播数据包的接口地址。如果有多个接口,则可以为您想要绑定的每个接口调用此函数。


我现在就会尝试这个。只有一个澄清 - 当你说“你有多个接口时,你可以为每个想要绑定的接口调用此函数”时,你仍然指的是单独的套接字,还是我可以在单个套接字上使用多个IP_ADD_MEMBERSHIP调用? - Rudolfs Bundulis
1
@RudolfsBundulis 一个套接字,多个IP_ADD_MEMBERSHIP调用,每个接口调用一次。 - dbush
谢谢,按照您的建议做确实有帮助。好的,最后一个问题 - 使用多个套接字的想法之一是能够知道网络接口已被关闭(我期望在这种情况下收到epoll / kqueue错误事件)。不确定是否会发生,但如果确实发生了,关闭接口会如何影响已加入多个组的套接字? - Rudolfs Bundulis
好的,我刚刚检查了一下,启用/禁用接口不会导致错误,所以我需要单独处理这个问题。 - Rudolfs Bundulis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接