2

My situation is as follows: there's an array of IP address. I will test each IP to connect to a remote server. If one IP connects, the rest IPs are ignored and not going to be connected.

I used the following Node.JS codes to do the work, but it seems not working. Please give some hints. Thanks!

// serverip is a var of string splitted by ";", e.g. "ip1;ip2;ip3"
var aryServerIP = serverip.split(";");
console.log(aryServerIP);

var ipcnt = aryServerIP.length; // ipcnt = 3, for example
for (ip in aryServerIP)
{
    console.log("to process: " + ipcnt); // error here: always print 3
    var net = require('net');
    var client = new net.Socket();
    var rdpport = 3389;
    client.connect(rdpport, aryServerIP[ip], function(){
        console.log("socket connected to " + aryServerIP[ip] + ":" + rdpport);
        client.destroy();
        if (0 != ipcnt)
        {
            // do some real connection work about aryServerIP[ip].
            ipcnt--;
        }
    });
    client.on('error', function(){
        console.log("fail to connect to " + aryServerIP[ip] + ":" + rdpport);
        ipcnt--;
    });
}

I know using ipcnt count to control the loop is bad, but I don't know how to control the Node.JS loop, when there's async function called in the loop...

1 Answer 1

1

Because your connect and error callbacks are both asynchronous, so they will both run after the for loop has completely finished.

What you need to do is set up a set of callbacks. For instance, rather than use a for loop, wrap your entire loop body in a function. If connect succeeds, then just do what you normally would, and if the error callback is called, then execute the wrapping function again. Something like this:

var async = require('async');
var net = require('net');
var rdpport = 3389;

function tryConnections(aryServerIP, callback){
  function connect(i){
    if (i === aryServerIP.length) return callback();

    var client = new net.Socket();
    client.connect(rdpport, aryServerIP[i], function(){
      callback(client);
    });
    client.on('error', function(){
      connect(i + 1)
    });
  }
  connect(0)
}

tryConnections(serverip.split(";"), function(client){
  if (client) // Successfully connected to something
  else // all ips failed
});

Another solution would be to use the Async library.

function tryConnections(aryServerIP, callback){
  async.detectSeries(aryServerIP, function(ip, cb){
    var client = new net.Socket();
    client.connect(rdpport, ip, function(){
      cb(client);
    });
    client.on('error', function(){
      cb();
    });
  }, callback);
}
Sign up to request clarification or add additional context in comments.

2 Comments

thanks! for your 1st solution, i think there's a pattern like this: var some_array = [...]; repeater(i) { if( i < length ) { asyncwork( function(){ repeater( i + 1 ) }) } } repeater(0) for your 2nd solution, I don't understand async lib now, and I'll look into it and ask question then. In your codes, the real work is done at the "if (client)" part, isn't it? I'd like to do it inside the loop. any ideas?
@McArthorLee Yup! I expanded my example a bit.

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.