3

I'm working on a function that iterates through a list of ports and calls its callback once one of the ports is available. Instead of waiting for each port response, I'd like to call a checkPortStatus function on all the ports and return when the first port returns as available.

Here's sample code runnable in node.js:

    // Check if a port is open (in use) or closed (available)
    function checkPortStatus(port, callback) {
      // Simulates real world checking of response from port by returning
      // after a random time.
      setTimeout(function() {
        // Simulates a few closed ports
        if (port === 3005 || port === 3006 || port === 3007) {
          callback('closed')
        }
        // Simulates a few open ports
        else {
          callback('open')
        }
      }, Math.floor(Math.random() * 200))
    }

    // Calls callback once any available port is found
    function findAnAvailablePort(startPort, endPort, callback) {
      var check = function(port) {
        checkPortStatus(port, function(status) {
          // If a port is 'closed', it's considered available
          if (status === 'closed') {
            callback(port)
          }
        })
      }
      for (var port = startPort; port <= endPort; port++) {
        check(port)
      }
    }

    findAnAvailablePort(3000, 3010, function(port) {
      console.log('AVAILABLE PORT: ' + port)
    });

    // Don't exit Node, wait for a response
    setTimeout(function() { console.log('FIN') }, 5000)

Results of running the code:

AVAILABLE PORT: 3005
AVAILABLE PORT: 3007
AVAILABLE PORT: 3006

Two questions:

  1. How do I call the callback only once? I want only the first port that matches to return.
  2. How do I check if all function callbacks returned? In this example, I need to return when all checkPortStatus return ports as unavailable.

1 Answer 1

1

initializing a few variables outside of the function should do the trick:

// Calls callback once any available port is found
var hasFoundPort = false;
var checkedPorts = 0;
function findAnAvailablePort(startPort, endPort, callback) {
  var check = function(port) {
    checkPortStatus(port, function(status) {
      checkedPorts++;
      // If a port is 'closed', it's considered available
      if (status === 'closed' && !hasFoundPort) { // only execute callback once
        callback(port)
        hasFoundPort = true;
      }
      if(checkedPorts == endPort - startPort + 1) // checked all ports
          console.log('finished checking');
    })
  }
  for (var port = startPort; port <= endPort; port++) {
    check(port)
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

You should also close the other ports when a port is already found.
Thanks David, I was over-thinking the problem. Your solution worked. Code can be found here: github.com/baalexander/node-portscanner

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.