2015-09-11 125 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 - 這個固定。 –

相關問題