Назначение joinGroup() в MulticastSocket

#java #sockets #multicast

#java #сокеты #многоадресная рассылка

Вопрос:

Я пытаюсь присоединиться к группе групповой рассылки после создания MulticastSocket.

Выполнение чего-то вроде:

 MulticastSocket mySocket = new MulticastSocket(4444);
mySocket.joinGroup(InetAddress.getByName("230.0.0.1")); // as an example
  

работает нормально. Однако, когда я использую конструктор MulticastSocket, который принимает SocketAddress в качестве параметра, к группе групповой рассылки не присоединяется и требуется отдельный вызов joinGroup().

 MulticastSocket mySocket = new MulticastSocket(new InetSocketAddress("230.0.0.1", 4444));
  

Почему это?

Спасибо!

Ответ №1:

Если я не ошибаюсь, многоадресная рассылка реализуется путем регистрации на коммутаторе локальной сети (с использованием joinGroup метода, который отправляет сообщение IGMP), а затем коммутатор пересылает все пакеты, отправленные на адрес многоадресной рассылки, на каждое зарегистрированное устройство. Если вы не вызываете joinGroup , сообщение о регистрации группы не отправляется, локальный коммутатор понятия не имеет, что вам небезразличны сообщения, и поэтому вы фактически не получаете никаких сообщений.

Некоторые коммутаторы более строго, чем другие, относятся к отправке: я видел некоторые коммутаторы, в которых устройство могло отправлять отправленные в группу групповой рассылки без регистрации, но не получать пакеты в группу групповой рассылки, и я видел другие коммутаторы, где устройству приходилось регистрироваться, чтобы успешно отправлять другим членам группы групповой рассылки или получать пакеты, отправленные в группу групповой рассылки.

Ответ №2:

Я думаю, что именно так был разработан протокол многоадресной рассылки / RFC. До тех пор, пока не будет вызвана «Объединенная группа», приложение будет игнорировать все многоадресные дейтаграммы. Это «объединенная группа», которая заставляет приложение принимать пакеты.

Подробнее об этом читайте здесь:http://tldp.org/HOWTO/Multicast-HOWTO-2.html

Переход к разделу Присоединение к группе многоадресной рассылки.конкретные подробности по ссылке выше.

Ответ №3:

Если вы не создаете MulticastSocket с групповым адресом, вам придется присоединиться к группе каким-либо другим способом. Иначе почему вы должны получать какие-либо сообщения для этой группы?

ПРИМЕЧАНИЕ: Построение с использованием группового адреса работает не на всех платформах AFAIK. Фактически конструктор, который принимает SocketAddress, указан так, чтобы использовать его в качестве локального адреса привязки, а не группы групповой рассылки. Я считаю, что указание адреса группы работает в Linux, но не на некоторых других платформах. Я бы использовал его так, как это задокументировано, и явно вызывал joinGroup(). Обратите внимание, что на хостах с несколькими домами вам может потребоваться вызвать joinGroup() для каждой доступной сетевой карты.

Ответ №4:

Femi верен: вам нужно позвонить joinGroup() , чтобы сообщить вашей сети, что вы заинтересованы в получении пакетов для этой группы многоадресной рассылки. (Имейте в виду, что весь IP-трафик является широковещательным; вот почему Wireshark и другие «беспорядочные» программы работают.)

Конструктор, который принимает IP-адрес, не указывает группу, к которой нужно присоединиться: он указывает, какую из ваших сетевых карт использовать. Если вы не укажете IP-адрес самой карты, вы запрашиваете карту, которая перенаправляет сообщения на указанный вами адрес. (Вау, это слишком много уточнений.) Так что вам все равно нужно joinGroup() после этого; просто только карта, которую вы … указано … будет получать пакеты.

Ответ №5:

Однако, когда я использую конструктор MulticastSocket, который принимает SocketAddress в качестве параметра, к группе групповой рассылки не присоединяется и требуется отдельный вызов joinGroup().

Параметр в конструкторе может иметь значение null. Таким образом, конструктор может быть не в состоянии вызвать joinGroup. Более того, в документе говорится, что это только привязка.

Я думаю, что не вызывать joingGroup() в конструкторе — это просто стандартная хорошая практика в Java. Если бы конструктор класса сделал это, пользователь потерял бы возможность контролировать, когда вызывается этот метод.

Он / Она может захотеть подготовить структуру данных перед присоединением к группе или дождаться завершения пользовательского сигнала или какого-либо другого процесса.