При широковещании клиент отправляет сообщение всем в сети, и все серверы отвечают. С помощью multicast вы определяете адрес группы многоадресной рассылки, и все серверы подписываются на нее. Затем клиент отправляет сообщение в группу, подписавшиеся серверы получают его и отвечают.
Многоадресная рассылка предназначена для случаев, когда один отправитель хочет отправить группе получателей, например, когда игровой клиент хочет отправить (потенциальной) группе серверов. Адреса многоадресной рассылки - это специальные адреса, для которых система знает, что они должны обрабатываться по-разному Получатель сообщает системе, что хочет получать сообщения, отправленные определенной группе, а отправитель отправляет сообщение на групповой адрес. В локальной сети это просто работает. В локальных сетях вам нужна многоадресная маршрутизация, которая не реализована в большинстве сетей. Но трансляция не будет работать и в локальных сетях.
Использование многоадресной рассылки гарантирует, что только системы в сети, которые заботятся о получении сообщения, получат его.
Как вы реализуете это зависит от языка программирования и т. Д.
Структура многоадресного адреса IPv6 выглядит следующим образом:
- Он всегда начинается с первых 8 битов адреса, установленных на 1, что означает, что первые два символа адреса будут
ff
;
- Третий символ (биты с 9 по 12) в адресе указывает флаги. В вашем случае вы, вероятно, захотите фиксированный адрес многоадресной рассылки для вашего приложения. В этом случае третьим символом будет a,
0
который указывает постоянно назначенный адрес многоадресной рассылки;
- 4-й символ (биты с 13 по 16) определяет область действия адреса. Скорее всего, вы будете использовать значение
2
для локальной связи (LAN).
Вместе это означает, что вы будете использовать адрес, начинающийся с ff02:
.
Многоадресные адреса назначаются IANA. RFC3307 определяет, как это сделать (критерием является экспертиза, поэтому нет необходимости писать RFC о том, что вы делаете или что-то в этом роде). В этом ответе я буду использовать адрес многоадресной рассылки ff02::db8:aa:bb
, который находится в блоке, зарезервированном для документации.
Вам не нужно иметь root-доступ для использования многоадресной рассылки. Следующие примеры Python3.3 могут быть запущены с учетной записью обычного пользователя:
Сервер (прослушивает многоадресный адрес):
#!/usr/bin/env python3.3
import socket
import struct
if_idx = socket.if_nametoindex('en0')
addr = 'ff02::db8:aa:bb'
port = 42424
group = socket.inet_pton(socket.AF_INET6, addr) + struct.pack("I", if_idx)
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, group)
sock.bind(('::', port))
while True:
msg, sender = sock.recvfrom(1024)
print('Received "%s" from "%s"' % (str(msg, 'UTF-8'), sender))
sock.sendto(bytes('Received %d bytes from you' % len(msg), 'UTF-8'), sender)
И клиент (отправка в многоадресную группу и прослушивание ответов):
#!/usr/bin/env python3.3
import socket
if_idx = socket.if_nametoindex('en0')
addr = 'ff02::db8:aa:bb'
port = 42424
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, if_idx)
sock.sendto(bytes('Hello there!', 'UTF-8'), (addr, port))
while True:
# You probably wait a certain time for replies, not indefinitely like this example
msg, sender = sock.recvfrom(1024)
print('Received "%s" from "%s"' % (str(msg, 'UTF-8'), sender))
Я использовал Python 3.3, потому что в старых версиях его нет socket.if_nametoindex
, но все остальное также должно работать в Python 2.
PS: использование существующей библиотеки или инфраструктуры для обнаружения сервисов, как предлагается в другом ответе, является хорошей идеей. Он будет использовать многоадресную рассылку под капотом, но избавит вас от необходимости разрабатывать и реализовывать свой собственный протокол.
Существуют протоколы для обнаружения услуг, которые современные приложения должны использовать вместо решений широковещательной или многоадресной передачи, независимо от того, используете ли вы IPv4 или IPv6.
Apple выдвигает mDNS / DNS-SD, а Microsoft - UPnP . Оба выполняют одни и те же цели для простого обнаружения службы, в то время как UPnP предлагает множество дополнительных функций.
Существуют свободно доступные библиотеки для обоих этих API для нескольких платформ. Соответствующие ОС включают встроенную поддержку. Linux предлагает поддержку через нестандартные системные компоненты, установленные по умолчанию в большинстве дистрибутивов.
Обратите внимание, что UPnP также можно использовать для настройки брандмауэра и, следовательно, может быть лучшим выбором для игр, которые планируют играть в Интернет, хотя вы не можете полагаться или требовать управления брандмауэром UPnP, поскольку многие пользователи не имеют совместимых маршрутизаторов или отключают особенность вне паранойи.
источник