2014-01-17 124 views
4

我试图通过node.js中的IPv6接收多播数据报。我在IPv4(udp4)上完全相同的方式没有问题,但尝试做相同的udp6给我EINVAL错误调用socket.addMembership。这里是我的代码:NodeJS数据报 - 接收IPv6多播

var dgram = require('dgram'); 
var server = dgram.createSocket('udp6'); 

var PORT = 12345; 
var MULTICAST_ADDRESS = 'ff7e:230::1234'; 

server.on('message', function (message, remote) { 
    console.log('Message from: ' + remote.address + ':' + remote.port +' - ' + message); 
}); 

server.on('listening', function() { 
    var address = server.address(); 
    console.log('UDP listening on ' + address.address + ":" + address.port); 
    server.addMembership(MULTICAST_ADDRESS); 
}); 

server.bind(PORT); 

这会导致:

Error: addMembership EINVAL 
      at new errnoException (dgram.js:454:11) 
      at Socket.addMembership (dgram.js:396:11) 
      at Socket.<anonymous> (/media/sf_projects/ipv6_multicast/server.js:57:10) 
      at Socket.EventEmitter.emit (events.js:92:17) 
      at startListening (dgram.js:141:10) 
      at dgram.js:213:7 
      at dns.js:72:18 
      at process._tickCallback (node.js:415:13) 
      at Function.Module.runMain (module.js:499:11) 
      at startup (node.js:119:16) 

当我注释掉server.addMembership(MULTICAST_ADDRESS);插座成功结合,但没有收到数据报。

我试图拨打addMembership与我的IPv6作为第二个参数,但这也给了EINVAL。

server.addMembership(MULTICAST_ADDRESS, 'fe80::a00:27ff:fed1:cac9'); 

我也试图套接字到特定的接口绑定:

server.bind(PORT, 'fe80::a00:27ff:fed1:cac9'); 

一个,这也给了我EINVAL上绑定方法。

这里是我的ifconfig输出:

eth0  Link encap:Ethernet HWaddr 08:00:27:d1:ca:c9 
         inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0 
         inet6 addr: fe80::a00:27ff:fed1:cac9/64 Scope:Link 
         UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 
         RX packets:8996 errors:0 dropped:0 overruns:0 frame:0 
         TX packets:6081 errors:0 dropped:0 overruns:0 carrier:0 
         collisions:0 txqueuelen:1000 
         RX bytes:8389966 (8.3 MB) TX bytes:510795 (510.7 KB) 

    lo  Link encap:Local Loopback 
         inet addr:127.0.0.1 Mask:255.0.0.0 
         inet6 addr: ::1/128 Scope:Host 
         UP LOOPBACK RUNNING MTU:65536 Metric:1 
         RX packets:356 errors:0 dropped:0 overruns:0 frame:0 
         TX packets:356 errors:0 dropped:0 overruns:0 carrier:0 
         collisions:0 txqueuelen:0 
         RX bytes:33534 (33.5 KB) TX bytes:33534 (33.5 KB) 
+0

我对你的多播地址有点困惑,ff7e:表示它是一个全球范围的多播地址,并且带有嵌入的rendez-vous点地址,但其余地址不匹配如RFC 3956中定义的嵌入式汇聚点地址模式。您能否告诉我们该地址如何?如定义? – Dubu

回答

4

如果你想绑定到本地链路(fe80:)地址你必须指定要链接。不幸的是,我还没有找到一种方法来为NodeJS做这件事。如果绑定到全球IPv6地址,它将起作用。

对于多播支持,您似乎没有运气...... NodeJS似乎只支持IPv4多播。对addMembership的调用是作为对uv_udp_set_membership的调用实现的,其中包含仅限IPv4的代码。它分析与inet_addr的IP地址,它调用setsockoptIP_ADD_MEMBERSHIP选项,而IPv6需要IPV6_ADD_MEMBERSHIP

似乎的NodeJS是有点落后于他们的IPv6实现:(

如果你有兴趣,你可以看到源代码如下:https://github.com/joyent/node/blob/master/deps/uv/src/unix/udp.c

+0

谢谢。我想我会在node.js问题跟踪器上为此创建一个issiue。我正在试验不同的地址。 –

+1

很高兴看到人们正在致力于IPv6支持!太糟糕了,NodeJS不如你:) –

+1

我为此创建了一个问题:[需要在dgram中支持IPv6多播](https://github.com/joyent/node/issues/6893) –