Java UDP多播,确定哪个组发送了数据包。

6
我正在制作一个应用程序,其中有一个特定的线程(MulticastListenerThread),它具有一个MulticastSocket,并侦听发送到该套接字所侦听的多播组的UDP(数据报)包。
这个可以工作。我可以加入多播组,向该组发送消息并通过MulticastSocket接收它。
然而,我想确定从接收方的角度来看,他从哪个多播组接收到了数据包。以下代码给出了数据包发起者的地址,而不是多播组的地址:
DatagramPacket packet = new DatagramPacket(buf, buf.length);
mlcSenderSocket.receive(packet);
String src_addr = packet.getAddress().getHostAddress();

发送数据包的代码如下:
InetAddress address = InetAddress.getByName(dest);
packet = new DatagramPacket(payload, payload.length,
    address, mlcEventPort);
LLog.out(this,"[NC] MLC packet Sent to ev port MLC " + mlcEventPort
    + " and to addr " + address);
mlcSenderSocket.send(packet);

有没有可能确定是哪个组发送了数据包?

编辑:

看起来这是不可能的。在性能影响方面(我正在为物联网设备工作),为每个多播组分配一个套接字(因此,每个组都有一个监听器线程)是否可行?可能会加入许多组(甚至数十个或数百个)。如果可行,那么我只需要手动保留已加入的组地址,并根据需要引用它。欢迎提出其他解决方法建议!


我想一个解决方法是维护多个MulticastSocket对象,每个对象加入一个组。这样很容易跟踪套接字和组之间的关联。 - Duncan Jones
我确实考虑过这个,但似乎过于冗余了,特别是因为可能有很多组要加入,而且这理论上是为受限的物联网设备设计的。然后我需要为每个MulticastSocket拥有一个监听器线程,这是我不愿意做的。 - user4346741
2个回答

2

没有群组发送数据包。特定IP地址的套接字发送了数据包,并且源IP地址在DatagramPacket中可用。多播数据包并不是来自多播组,而是被寻址到多播组。


我理解。但是,套接字只接受数据包是因为它已经加入了某个特定的组,所以在某个层面上,数据包来自哪个组的信息必须可用,对吧? 就像我的主要帖子中的评论所说,如果每个套接字只有一个组,这个信息就很明显了,但我有多个组。 - user4346741
发送数据包的套接字可能已经加入了零个或多个组。因此,哪个组发送它的概念是没有意义的。你真正需要的是数据包被发送到了哪个组,这个信息在C级别是可用的,但据我所知,在Java级别上还不可用,除非它出现在DatagramSocketChannel的修订中。 - user207421
很不幸,感谢您的回复,我在主贴中编辑了一个小问题。 - user4346741
我认为使用数十个甚至数百个套接字并没有任何问题。你可以尝试这种方式,看看是否会出现问题。如果确实有问题,你可以通过使用非阻塞模式下的java.nio.channels.DatagramSocketChannelSelector来减少线程需求。 - user207421

0

是的,你可以将一个MulticastSocket加入到多个组中,例如:

InetAddress group;

MulticastSocket s=new MulticastSocket(12345);
NetworkInterface ni=NetworkInterface.getByName("eth1");

group=InetAddress.getByName("239.255.10.10");
s.joinGroup(new InetSocketAddress(group,12345),ni);

group=InetAddress.getByName("239.255.10.11");
s.joinGroup(new InetSocketAddress(group,12345),ni);

然后您会收到像这样的数据报:

DatagramPacket datagram=s.receive(datagram);

很遗憾,在DatagramPacket对象中没有Java API调用可以让您确定发送方针对的是两个组中的哪一个,您只能获取它从套接字接收到的网络接口的IP地址和发送方的IP地址(从数据报中获取)。

要实现您想要做的事情,您需要创建多个MulticastSocket对象,并分别监听每个组。您可以使用自己的线程或NIO同时监听它们。


在Java中,您无法“获取接收到数据的网络接口的IP地址”。您可以获取发送数据的IP地址。 - user207421
当然可以,这都是标准的基础操作,并且在套接字对象中可用。接收数据报无法检索MC组信息。我的文字表述不清,没能说明从哪里可以获取什么。我已经澄清了。 - Andy Brown
如果套接字绑定到一个接口,你可以获取它所绑定的接口。但是,如果它绑定到INADDR_ANY,通常情况下你就无法获取。 - user207421

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