2014-12-19 1 views
5

Я создаю приложение, в котором есть определенный поток (MulticastListenerThread), который имеет MulticastSocket и прослушивает пакеты UDP (датаграммы), отправленные в группу многоадресной рассылки, ,Java UDP multicast, определить, какая группа отправила пакет

Это работает. Я могу присоединиться к группе многоадресной передачи, отправить сообщение этой группе и получить ее через 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); 

Является ли это вообще возможно определить какая группа отправила пакет?

Редактировать:

Похоже, что это невозможно. Что касается воздействия на производительность (я работаю на устройствах IoT), назначил бы сокет на группу мультивещания (и, следовательно, поток слушателей на группу), жизнеспособный? Потенциально многие группы могут быть объединены (с точки зрения десятков или сотен даже). Если это жизнеспособно, тогда мне просто нужно сохранить присоединенный групповой адрес где-то вручную и обратиться к нему по мере необходимости. Предложения по другим работам приветствуются!

+0

Я полагаю, что работа вокруг будет заключаться в том, чтобы поддерживать несколько объектов MulticastSocket, по одному для каждой группы, к которой вы хотите присоединиться. Тогда будет достаточно легко отслеживать связь между сокетами и группами. –

+0

Я действительно думал об этом, но это кажется чрезмерно чрезмерным, тем более что я мог бы потенциально много групп присоединиться, и это (теоретически) предназначено для ограниченных устройств IoT. Тогда мне понадобится поток прослушивателя в MulticastSocket, что я бы предпочел не делать. –

ответ

2

No группа отправила пакет. Сокет на определенном IP-адресе отправил пакет, а IP-адрес источника доступен в DatagramPacket. Пакеты многоадресной рассылки не поступают из групп многоадресной рассылки, они адресованы для групповых групп.

+0

Я понимаю. Но все же сокет принимает только пакет, потому что он присоединился к определенной группе, поэтому на каком-то уровне должна быть доступна информация о том, из какой группы возникает пакет, нет? Как и комментарий к моему основному сообщению, если у меня есть только одна группа для каждого сокета, эта информация будет очевидна, но у меня много. –

+0

Сокет, который отправил пакет, возможно, присоединил нулевые группы или несколько. Понятие о том, какая группа послала его, поэтому не имеет смысла. Вам действительно нужна группа, в которую был отправлен пакет * to, *, и эта информация доступна на уровне C, но не так, насколько я знаю на уровне Java, если только она не появляется в версиях для DatagramSocketChannel. ' – EJP

+0

Несчастливо. Спасибо за ответ, я редактировал свой основной пост с небольшим новым вопросом. –

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); 

К сожалению, нет никакого вызова Java API в DatagramPacket, который позволит вам определить, какая из двух групп была нацелена отправителем, все, что вы можете получить, - это IP-адрес сетевого интерфейса, на котором он был получен (из сокета) и IP-адреса отправителя (из дейтаграммы).

Для достижения того, что вы хотите сделать, вам понадобится создать несколько объектов MulticastSocket и послушать одну группу на каждый сокет. Вы можете использовать свои собственные потоки или NIO, чтобы слушать их все одновременно.

+0

Вы не можете получить IP-адрес сетевого интерфейса на котором он был получен »на Java. Вы можете получить IP-адрес, с которого он был отправлен. – EJP

+0

Да, конечно, вы можете, это все ванильный стандарт и доступно на объекте сокета. Это информация группы MC, которая не может быть получена из принятой дейтаграммы. Мой текст был неясным относительно того, что вы можете получить от того места. Я уточнил это. –

+0

Вы можете получить интерфейс, к которому привязан сокет, * если * привязан к интерфейсу. Если это связано с INADDR_ANY, как обычно, вы не можете. – EJP