使用Node.js,我们可以创建服务器并监听随机端口:
var server = net.createServer();
server.listen(0, '127.0.0.1');
第一个参数port 0
表示选择一个随机端口,127.0.0.1
表示只在localhost上侦听as documented。
Node.js是否选择了一个未使用的端口?如果Node.js碰巧选择已经打开并绑定到另一个应用程序的端口,我是否必须自己检查并重试?它选择任何旧端口,还是只选择用户端口(> 1024)?
答案 0 :(得分:26)
操作系统分配端口号。见https://github.com/joyent/node/blob/v0.6.11/lib/net.js#L780-783
在OS X上,分配是顺序的,userland并且不检查端口以验证它是否未被使用。
在Ubuntu 11.04上,分配是随机的,userland,也不检查端口是否正在使用。
以下脚本可用于在其他平台上进行测试。为了验证端口是userland,我通过bash管道运行脚本10,000次,以及零匹配的grep -c“port:[0-9] {1,3}”。
var net = require('net'),
firstPort;
(function createServer(port) {
var server = net.createServer();
server.listen(port, function() {
address = server.address();
if (port === 0) {
if (firstPort === undefined) {
firstPort = address.port;
// cause a EADDRINUSE in 10 more sockets for sequential platforms
// without this, will run out of fd's before hitting EADDRINUSE
createServer(firstPort + 10);
console.log('addr in use port trap: ', firstPort + 10);
} else {
// on OS X (sequential) this will increment the OS's sequential counter
// and not cause EADDRINUSE
createServer(address.port + 1);
}
createServer(0);
}
console.log("requested port:", port, " binded port:",address.port);
});
})(0);
答案 1 :(得分:5)
Node.js是否选择未使用的端口?
是,该端口将是可用端口。 操作系统选择一个未使用的端口,而不是Node.js,但是从最终用户的角度来看,这大致相同。
毫无疑问,在最初于2012年发布此问题时,文档的措词有所不同,但截至目前(2019年1月),it is explicit about this:“如果端口被省略或为0,则操作系统将分配任意未使用的端口...”。
我是否必须检查一下自己并重试Node.js是否碰巧选择了一个已经打开并绑定到另一个应用程序的端口?
不,您不会。无论如何,您都应该处理错误,因为许多事情都可能出错。但是,无需编写额外的代码来测试端口的可用性。
它选择任何旧端口还是仅选择用户端口(> 1024)?
据我所知,它将永远是一个没有特权的端口。
对于像macOS这样的操作系统,它们顺序分配可用端口,下面的代码显示该操作系统将在端口不可用时跳过该端口。
// Testing for macOS, which supplies available ports sequentially.
var net = require('net');
createServer(0, function () {
var port = this.address().port;
console.log('server was assigned port ' + port);
createServer(port+1, function () {
var port = this.address().port;
console.log('server was assigned port ' + port);
createServer(0, function () {
var port = this.address().port;
// This line will show that the OS skipped the occupied port and assigned the next available port.
console.log('server was assigned port ' + port);
});
});
});
function createServer(port, callback) {
console.log('create server with port ' + port);
var server = net.createServer();
server.listen(port, callback).unref();
}