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

Bra*_*rad 11 port node.js

使用Node.js,我们可以创建服务器并监听随机端口:

var server = net.createServer();
server.listen(0, '127.0.0.1');
Run Code Online (Sandbox Code Playgroud)

第一个参数port 0表示选择一个随机端口,并127.0.0.1指示仅在本地主机上侦听,如文档所述.

Node.js是否选择了一个未使用的端口?如果Node.js碰巧选择已经打开并绑定到另一个应用程序的端口,我是否必须自己检查并重试?它选择任何旧端口,还是只选择用户端口(> 1024)?

Kru*_*rut 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);
Run Code Online (Sandbox Code Playgroud)

  • 下面的代码演示了它在 macOS 上跳过了一个被占用的端口:https://gist.github.com/Trott/4caed3e2ce93a92318ec1d54aedbbc80 (2认同)

Tro*_*ott 5

Node.js是否选择了一个未使用的端口?

是的,该端口将是一个可用端口.该操作系统将选择一个端口,是不是在使用,而不是Node.js的,但是从最终用户的角度来看,这是更多或更少同样的事情.

毫无疑问,该问题在2012年最初发布此问题时有不同的措辞,但截至目前(2019年1月),显而易见:"如果端口被省略或为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();
}
Run Code Online (Sandbox Code Playgroud)