Node.js dgram 在 udp6 和 udp4 上绑定抛出 EADDRINUSE
Node.js dgram bind on udp6 and udp4 throws EADDRINUSE
我最近通过 npm 安装 n
然后调用 n stable
.
将我的 node.js 版本从 0.10.31 升级到 4.0.0
有了新的节点版本,我现有的代码就崩溃了。
此代码:
var d = require("dgram");
var s = d.createSocket("udp4");
s.bind(9000);
var s6 = d.createSocket("udp6");
s6.bind(9000);
产生以下错误:
events.js:141
throw er; // Unhandled 'error' event
^
Error: bind EADDRINUSE ::0:9000
at Object.exports._errnoException (util.js:837:11)
at exports._exceptionWithHostPort (util.js:860:20)
at dgram.js:213:18
at doNTCallback3 (node.js:440:9)
at process._tickCallback (node.js:346:17)
at Function.Module.runMain (module.js:477:11)
at startup (node.js:117:18)
at node.js:951:3
一旦 IPv6 UDP 套接字想要绑定到端口 9000。
没有旧节点进程运行,也没有程序已经在监听端口 9000。
如果我将第二个绑定命令更改为 s6.bind(9001);
,则不会发生错误。如果我更改顺序(首先绑定 udp6,然后绑定 udp4),则当 udp4 套接字尝试绑定时将出现错误。
会不会是新节点版本试图使用旧的核心模块之类的?
谁能解释一下这种奇怪的行为?
提前感谢您的帮助!
此致
对比老node版本0.10.31和4.0.0的源码后,我发现我的代码不能用的原因:
因为node.js没有为IPv6 UDP套接字设置标志IPV6_V6ONLY,如果启用SO_REUSEADDR,一个IPv6套接字和一个IPv4套接字只能监听同一个端口。旧节点版本(实际上是使用旧版本的 libuv 库)隐式设置此选项。新版本允许用户选择,但默认情况下是禁用的。
所以我必须将我的代码更改为以下代码才能使其正常工作:
var d = require("dgram");
var s = d.createSocket({type:"udp4",reuseAddr:true});
s.bind(9000);
var s6 = d.createSocket({type:"udp6",reuseAddr:true});
s6.bind(9000);
我最近通过 npm 安装 n
然后调用 n stable
.
有了新的节点版本,我现有的代码就崩溃了。
此代码:
var d = require("dgram");
var s = d.createSocket("udp4");
s.bind(9000);
var s6 = d.createSocket("udp6");
s6.bind(9000);
产生以下错误:
events.js:141
throw er; // Unhandled 'error' event
^
Error: bind EADDRINUSE ::0:9000
at Object.exports._errnoException (util.js:837:11)
at exports._exceptionWithHostPort (util.js:860:20)
at dgram.js:213:18
at doNTCallback3 (node.js:440:9)
at process._tickCallback (node.js:346:17)
at Function.Module.runMain (module.js:477:11)
at startup (node.js:117:18)
at node.js:951:3
一旦 IPv6 UDP 套接字想要绑定到端口 9000。
没有旧节点进程运行,也没有程序已经在监听端口 9000。
如果我将第二个绑定命令更改为 s6.bind(9001);
,则不会发生错误。如果我更改顺序(首先绑定 udp6,然后绑定 udp4),则当 udp4 套接字尝试绑定时将出现错误。
会不会是新节点版本试图使用旧的核心模块之类的?
谁能解释一下这种奇怪的行为?
提前感谢您的帮助!
此致
对比老node版本0.10.31和4.0.0的源码后,我发现我的代码不能用的原因:
因为node.js没有为IPv6 UDP套接字设置标志IPV6_V6ONLY,如果启用SO_REUSEADDR,一个IPv6套接字和一个IPv4套接字只能监听同一个端口。旧节点版本(实际上是使用旧版本的 libuv 库)隐式设置此选项。新版本允许用户选择,但默认情况下是禁用的。
所以我必须将我的代码更改为以下代码才能使其正常工作:
var d = require("dgram");
var s = d.createSocket({type:"udp4",reuseAddr:true});
s.bind(9000);
var s6 = d.createSocket({type:"udp6",reuseAddr:true});
s6.bind(9000);