#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. Если бы конструктор класса сделал это, пользователь потерял бы возможность контролировать, когда вызывается этот метод.
Он / Она может захотеть подготовить структуру данных перед присоединением к группе или дождаться завершения пользовательского сигнала или какого-либо другого процесса.