Node.js如何选择随机端口?

时间:2012-03-28 04:14:18

标签: node.js port

使用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)?

2 个答案:

答案 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();
}