[英]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套接字嘗試綁定時將顯示錯誤。
是新的節點版本嘗試使用舊的核心模塊還是類似的東西?
誰能解釋這個奇怪的行為?
預先感謝您的任何幫助!
問候
將舊節點版本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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.