javascript - Node.js dgram 绑定(bind)在 udp6 和 udp4 上抛出 EADDRINUSE

标签 javascript node.js sockets datagram

我最近通过 npm 安装 n,然后调用 n stable,将我的 node.js 版本从 0.10.31 升级到 4.0.0。

使用新的 Node 版本,我现有的代码崩溃了。

这段代码:

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 套接字想要绑定(bind)到端口 9000。

没有旧 Node 进程在运行,也没有程序已经在监听端口 9000。

如果我将第二个绑定(bind)命令更改为s6.bind(9001);,则不会发生错误。如果我更改顺序(首先绑定(bind) udp6,其次绑定(bind) udp4),那么当 udp4 套接字尝试绑定(bind)时就会出现错误。

新的 Node 版本是否会尝试使用旧的核心模块或类似的东西?

谁能解释一下这种奇怪的行为吗?

预先感谢您的帮助!

问候

最佳答案

对比旧 Node 版本0.10.31和4.0.0的源代码后,我找到了我的代码不再工作的原因:

由于node.js没有为IPv6 UDP套接字设置IPV6_V6ONLY标志,因此如果启用SO_REUSEADDR,则1个IPv6套接字和1个IPv4套接字只能监听同一端口。旧的node版本(实际上是使用的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);

关于javascript - Node.js dgram 绑定(bind)在 udp6 和 udp4 上抛出 EADDRINUSE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32521412/

相关文章:

c++ - 使用 socketpair : hangs reading output from child process 进行双向通信

python - 通过Kafka和套接字通信流式传输视频

javascript - 使用 javascript 更改 Spotfire 文档属性值

javascript - 为什么这个 ng-idle 实现没有连接模式和样式?

javascript - 从表列调用 javascript 函数

node.js - Google reCAPTCHA无法在Electron BrowserWindow中解决

node.js - 在 node.js 中模拟数据库?

sockets - Rust 非阻塞 openssl 流

javascript - Codecademy 给我带来了困难,我做错了什么?

javascript - 带有源映射的调试器中的损坏名称