Ответ 1
Идентификатор области → номер интерфейса
В IPv6 существует понятие scope_id адреса, который должен указывать контекст для IP-адреса, и, как правило, просто означает, к какому интерфейсу он доступен. В то время как в обласках есть конкретные имена ОС, каждый из них просто преобразуется в номер интерфейса, причем 0 обычно означает стандартную систему.
В многоадресной рассылке IPv6 этот scope_id предоставляется непосредственно IP_ADD_MEMBERSHIP и IP_MULTICAST_IF вместо предоставления ip, связанного с интерфейсом, как это делает IPv4.
сглаживание оболочки v6 различий
node (через libuv) скрывает эту разницу для вас в addMembership
, просматривая область видимости с "адрес интерфейса", который вы предоставляете.
К сожалению, начиная с простого IP-адреса и получения области не имеет большого смысла (вся суть области заключается в том, что IP может иметь разные применения в разных областях). Таким образом, libuv может только заполнять область, если вы явно предоставляете ее в конце адреса, используя формат %[scope]
.
Использование адресов с явными областями
Кажется, что это вокруг:
sock.bind('36912', '::', () => {
sock.addMembership('ff02::1:3', '::%eth2');
...
sock.send(buf, 0, buf.length, 36912, 'ff02::1:3%eth2');
Где:
-
с помощью
::
(или без адреса) в bind необходимо, так как вы комбинируете прием, который будет фильтровать многоадресный адрес на этом с помощью отправки, для которой необходим нормальный адрес. -
с помощью
%[iface#]
заставляет область действия этого интерфейса #. -
Второй аргумент addMembership действительно может начинаться с любого адреса, поскольку мы вынуждаем область действия, а остальная часть отбрасывается.
-
Обычно сокет отправки разделяется и получает другой порт или анонимный порт, так как вы либо ограничены тем, что можете настроить, либо рискуете получить ошибки EADDRINUSE для слишком близких сокетов.