Bra*_*rad 10 multicast ipv6 node.js
我正在通过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);
Run Code Online (Sandbox Code Playgroud)
该脚本运行,我看到使用Wireshark发送/接收的数据包,但两端都没有在控制台中显示它们.
我究竟做错了什么?有什么方法可以通过IPv6发送和接收基本多播?
在IPv6中,存在一个地址的scope_id的概念,该地址应该指示IP地址的上下文,并且通常仅表示它可以在哪个接口上访问.虽然范围具有特定于操作系统的名称,但每个范围仅转换为接口编号,0通常表示系统的默认值.
在IPv6多播中,此scope_id直接提供给IP_ADD_MEMBERSHIP和IP_MULTICAST_IF,而不是像IPv4那样提供与接口关联的ip.
node(通过libuv)addMembership通过从您提供的"接口地址"中查找scope_id来为您隐藏这种差异.
不幸的是,从一个IP开始并获得一个范围并没有多大意义(范围的重点是IP可以在不同的范围内有不同的用途.)因此libuv只能填写一个范围,如果您使用%[scope]格式明确地在地址的末尾提供它.
解决这个问题的方法似乎是:
sock.bind('36912', '::', () => {
sock.addMembership('ff02::1:3', '::%eth2');
...
sock.send(buf, 0, buf.length, 36912, 'ff02::1:3%eth2');
Run Code Online (Sandbox Code Playgroud)
哪里:
::在绑定中使用(或没有地址)是必要的,因为你要组合接收,这将过滤多播地址与需要普通地址的发送.
使用%[iface#]强制此接口的范围#.
addMembership的第二个参数实际上可以从任何地址开始,因为我们强制范围,其余的被丢弃.
通常,发送套接字是分开的,并且给定一个不同的端口或匿名端口,因为您要么可以配置,要么因为套接字太相似而有获得EADDRINUSE错误的危险.
| 归档时间: |
|
| 查看次数: |
686 次 |
| 最近记录: |