2015-09-11 124 views
2

我最近通过安装n通过npm将我的node.js版本从0.10.31升级到4.0.0,然后调用n stableNode.js dgram绑定到udp6和udp4引发EADDRINUSE

随着新的节点版本,我现有的代码破坏。

此代码:尽快

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

没有旧节点处理

var d = require("dgram"); 
var s = d.createSocket("udp4"); 
s.bind(9000); 
var s6 = d.createSocket("udp6"); 
s6.bind(9000); 

产生以下错误运行,也没有程序已经在端口9000监听。

如果我将第二个绑定命令更改为s6.bind(9001);,则不会发生该错误。如果我更改顺序(udp6首先绑定,udp4秒),则当udp4套接字尝试绑定时会显示错误。

难道是新的节点版本试图使用旧的核心模块或类似的东西?

任何人都可以解释这种奇怪的行为?

非常感谢您的帮助!

问候

回答

4

的旧节点版本的源代码比较0.10.31到4.0.0后,我找到了原因我的代码不再起作用的原因:

因为Node.js的呢如果启用了SO_REUSEADDR,则不会为IPv6 UDP套接字设置标志IPV6_V6ONLY,而是一个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); 
+0

问题继续在节点v6.9.4 - 这个固定。 –

相关问题