从节点,此可用地址列表:
var os = require('os');
os.networkInterfaces()
打印:
{ lo0:
[ { address: '::1',
netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
family: 'IPv6',
mac: '00:00:00:00:00:00',
scopeid: 0,
internal: true },
{ address: '127.0.0.1',
netmask: '255.0.0.0',
family: 'IPv4',
mac: '00:00:00:00:00:00',
internal: true },
{ address: 'fe80::1',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '00:00:00:00:00:00',
scopeid: 1,
internal: true } ],
en0:
[ { address: 'fe80::2acf:e9ff:fe1f:3939',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '28:cf:e9:1f:39:39',
scopeid: 4,
internal: false },
{ address: '10.0.0.8',
netmask: '255.255.255.0',
family: 'IPv4',
mac: '28:cf:e9:1f:39:39',
internal: false } ],
awdl0:
[ { address: 'fe80::e46a:6cff:fe68:a76a',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: 'e6:6a:6c:68:a7:6a',
scopeid: 8,
internal: false } ] }
但是如果我尝试创建特定的udp套接字,我可以绑定udp4而不是udp6套接字。
var dgram = require('dgram');
var udp4 = dgram.createSocket('udp4');
udp4.bind(null, '10.0.0.8');
udp4.address()
打印
{ address: '10.0.0.8', family: 'IPv4', port: 65061 }
但
var udp6 = dgram.createSocket('udp6');
udp6.bind(null, 'fe80::e46a:6cff:fe68:a76a');
抛出:
Error: bind EADDRNOTAVAIL fe80::e46a:6cff:fe68:a76a
at Object.exports._errnoException (util.js:874:11)
at exports._exceptionWithHostPort (util.js:897:20)
at dgram.js:213:18
at doNTCallback3 (node.js:452:9)
at process._tickDomainCallback (node.js:399:17)
同样的事情发生在地址'fe80 :: 2acf:e9ff:fe1f:3939'。注意,我在Nodes的REPL中逐个运行这些语句,所以在我尝试检查地址时绑定已经完成。
我能做到
udp6.bind()
udp6.address()
打印
{ address: '::', family: 'IPv6', port: 51897 }
但这并没有告诉我它应该绑定哪个地址(我需要通知其他同行)。
为什么我可以绑定到特定的IPv4地址而不是IPv6地址?这似乎不一致。这可能是运行时中的错误吗? Relevant bug in Node issue tracker.
我需要有udp套接字,这些套接字具有反映os.networkInterfaces中可用内容的特定地址,因为我是building和ICE agent。
我正在使用Node v4.2.2。
答案 0 :(得分:3)
好的,所以看起来我需要Link-local addresses中的背景。
要点是使用IPv4,您通常使用DHCP之类的协议来分配本地IP地址。如果你没有,你可以选择一个并希望你不要与网络上的其他主机发生冲突。这样的地址称为"链接本地地址。"这些在IPv4中是可选的,现在在IPv6中是必需的。链接本地地址始终具有IPv6地址的前缀fe80 ::前缀。
在Node.js中,您可以侦听链接本地地址,但必须使用接口名称后缀地址字符串,例如:
udp6.bind(null, 'fe80::e46a:6cff:fe68:a76a%en0');
特别是可以通过运行ifconfig找到该字符串。
然后,如果其他对等方在同一网络上,则可以与您联系,但是他们也必须在同一网络上指定网络设备的接口。离。
nc6 -u fe80::2acf:e9ff:fe1f:3939%wlp3s0 65022
wlp3s0是朋友无线网卡的接口。
如果他们插入以太网并在同一网络上运行,他们就可以通过以太网接口发送,但除非它连接到同一个本地网络,否则无法发送。
此外,我发布的IP地址显示我的家庭路由器没有分配IPv6地址。在工作中,我得到一个IPv6地址,所以我可以听一个非fe80前缀地址没问题。在工作中,os.networkInterfaces()看起来更像是:
en0:
[ { address: 'fe80::2acf:e9ff:fe1f:3939',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '28:cf:e9:1f:39:39',
scopeid: 4,
internal: false },
{ address: '10.252.28.131',
netmask: '255.255.248.0',
family: 'IPv4',
mac: '28:cf:e9:1f:39:39',
internal: false },
{ address: '2620:101:80fc:224:2acf:e9ff:fe1f:3939',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '28:cf:e9:1f:39:39',
scopeid: 0,
internal: false },
{ address: '2620:101:80fc:224:4d78:1087:39a2:65d7',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '28:cf:e9:1f:39:39',
scopeid: 0,
internal: false } ],
所以我可以成功绑定到任何2620:前缀地址。
最后,对于我的ICE代理,updated draft spec表示"对应于IPv6链接本地地址的主机候选者不得收集。"