При широковещании клиент отправляет сообщение всем в сети, и все серверы отвечают. С помощью 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: использование существующей библиотеки или инфраструктуры для обнаружения сервисов, как предлагается в другом ответе, является хорошей идеей. Он будет использовать многоадресную рассылку под капотом, но избавит вас от необходимости разрабатывать и реализовывать свой собственный протокол.