简体   繁体   English

使用相同的套接字发送和接收 UDP 多播数据包

[英]Send and receive UDP multicast packets with the same socket

I could not find a working example for this, so I am going to post a question (and let's see if I can reduce this to an MVP code example).我找不到一个工作示例,所以我将发布一个问题(让我们看看是否可以将其简化为 MVP 代码示例)。 So, I need to do mdns queries, I can use two sockets (one for sending / second for receiving) but so far I have not been able to make it work with a single socket.所以,我需要做 mdns 查询,我可以使用两个套接字(一个用于发送/第二个用于接收),但到目前为止我还无法使其与单个套接字一起工作。

So the steps that I am performing are:所以我正在执行的步骤是:

Enumerate all the interface addresses on the host.枚举主机上的所有接口地址。 Then for each host:然后对于每个主机:

  1. Create a non blocking UDP socket创建非阻塞 UDP 套接字
  2. bind() to either the interface address:5353 or the multicast group address (either of these cause either read or write to fail) bind() 到接口地址:5353 或多播组地址(这些都会导致读取或写入失败)
  3. Set IP_MULTICAST_IF to the local interface将 IP_MULTICAST_IF 设置为本地接口
  4. IP_ADD_MEMBERSHIP to the multicast group IP_ADD_MEMBERSHIP 到多播组
  5. Add the sockets for read/write in kqueue在 kqueue 中添加用于读/写的套接字

So depending on what I do in step 2 either read or write fails:因此,根据我在第 2 步中执行的操作,读取或写入失败:

  1. If I bind the socket to the multicast group I get read notifications from the kqueue and can read packets, but when I get a write notification from the kqueue and try to write it fails with errno 49如果我将套接字绑定到多播组,我会从 kqueue 收到读取通知并可以读取数据包,但是当我从 kqueue 收到写入通知并尝试写入时,它会失败并显示 errno 49
  2. If I bind the socket to the interface address I can send the packets but no read notifications ever arrive from the kqueue如果我将套接字绑定到接口地址,我可以发送数据包,但没有读取通知从 kqueue 到达

So which address I need to bind to then?那么我需要绑定到哪个地址呢? Also, since the IP_ADD_MEMBERSHIP parameter ip_mreq has the interface field, do I really need the IP_MULTICAST_IF ?另外,由于IP_ADD_MEMBERSHIP参数ip_mreq有 interface 字段,我真的需要IP_MULTICAST_IF吗?

If you bind to a specific interface address (on Linux at least), you'll be unable to receive multicast.如果您绑定到特定的接口地址(至少在 Linux 上),您将无法接收多播。 If you bind to a multicast address, you can't send.如果绑定到多播地址,则无法发送。

What you need to do is bind to INADDR_ANY , then when you set the IP_ADD_MEMBERSHIP option, you set the interface address that you want to receive multicast packets on.您需要做的是绑定到INADDR_ANY ,然后在设置IP_ADD_MEMBERSHIP选项时,设置要接收多播数据包的接口地址。 If you have multiple interfaces, you can call this for each interface you want to bind to.如果您有多个接口,则可以为要绑定到的每个接口调用此方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM