Подтвердить что ты не робот

Как Node.js выбирают случайные порты?

С Node.js мы можем создать сервер и прослушивать случайный порт:

var server = net.createServer();
server.listen(0, '127.0.0.1');

Первый параметр, порт 0, указывает на выбор случайного порта, а 127.0.0.1 указывает на прослушивание только на локальном хосте, как задокументировано.

Выбрал ли Node.js порт, который не используется? Нужно ли мне проверять это и повторять попытку, если Node.js происходит, чтобы выбрать порт, который уже открыт и привязан к другому приложению? Может ли он выбрать любой старый порт или только пользовательские порты ( > 1024)?

4b9b3361

Ответ 1

Выбирает ли Node.js порт, который не используется?

Да, порт будет доступным. Операционная система выбирает порт, который не используется, а не Node.js, но с точки зрения конечного пользователя, это более или менее то же самое.

Без сомнения, документация имела другую формулировку в то время, когда этот вопрос был первоначально опубликован в 2012 году, но на данный момент (январь 2019 года) об этом явно сказано: "Если порт опущен или равен 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();
}

Ответ 2

ОС назначает номер порта. См. https://github.com/joyent/node/blob/v0.6.11/lib/net.js#L780-783

В OS X назначение является последовательным, userland и не проверяет порт, чтобы убедиться, что он не используется.

В Ubuntu 11.04 назначение является случайным, userland и также не проверяет, используется ли порт.

script ниже можно использовать для тестирования на других платформах. Чтобы проверить, что порты являются userland, я запускал script 10 000 раз через bash, подключенный к порту grep -c: [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 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 sequential counter
        // and not cause EADDRINUSE
        createServer(address.port + 1);
      }
      createServer(0);
    }
    console.log("requested port:", port, " binded port:",address.port);
  });  
})(0);