node.js - 使用 Node.js 进行 IPv6 多播

标签 node.js ipv6 multicast

我正在尝试通过 VPN 使用 IPv6 UDP 多播。我试过以下代码:

const dgram = require('dgram');

let sock = dgram.createSocket('udp6', {
  reuseAddr: true
});

sock.on('message', (data, source) => {
  console.log('on message', arguments);
});

sock.bind('36912', '2620:9b::1944:e598', () => {
  sock.addMembership('ff02::1:3', '2620:9b::1944:e598');
});


setInterval(() => {
  let buf = Buffer.from((new Date()).toString());
  sock.send(buf, 0, buf.length, 36912, 'ff02::1:3');
}, 500);

脚本运行,我看到正在使用 Wireshark 发送/接收数据包,但两端都没有在控制台中显示它们。

Wireshark UDP Capture

我做错了什么?使用 IPv6 发送和接收基本多播的方法是什么?

最佳答案

Scope id -> 接口(interface)编号

在 IPv6 中,有一个地址的 scope_id 的概念,它应该指示 IP 地址的上下文,通常只表示它可以访问的接口(interface)。虽然作用域具有特定于操作系统的名称,但每个仅转换为接口(interface)编号,0 通常表示系统的默认值。

在 IPv6 多播中,此 scope_id 直接提供给 IP_ADD_MEMBERSHIP 和 IP_MULTICAST_IF,而不是像 IPv4 那样提供与接口(interface)关联的 ip。

v6 差异的封装平滑

node(通过 libuv)通过从您提供的“接口(interface)地址”中查找 scope_id 在 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#] 强制此接口(interface)的作用域#。

  • addMembership 的第二个参数实际上可以从任何地址开始,因为我们强制作用域,其余的被丢弃。

  • 通常,发送套接字是分开的,并被赋予不同的端口或匿名端口,因为您可以配置的内容受到限制,或者由于套接字过于相似而有出现 EADDRINUSE 错误的危险。

关于node.js - 使用 Node.js 进行 IPv6 多播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38448369/

相关文章:

node.js - nodejs 异步函数是否使用所有 CPU 内核?

使用 node-inspector 调试 jasmine-node 测试

node.js - 在 Node.js 中何时使用 next() 并返回 next()

mqtt - Mosquitto_sub 错误 : connection refused, 仅限 IPv6

ios - 如何正确地通过 IPv6 发送电子邮件?

sockets - 如何在多宿主服务器的非默认接口(interface)上接收多播数据

c# - UDP - 发送多播消息并监听响应给出 SocketException

javascript - 有没有 ? ("safe operator") Typescript 中的替代方法来处理空值?

ios - App rejected NSUrlConnection IPv6 网络问题 iOS

java - 如何在多宿主系统(Java、Linux)上使用多播