【问题标题】:Callback was already calleld with async.parallel function回调已经用 async.parallel 函数调用
【发布时间】:2016-11-20 21:42:24
【问题描述】:

我正在使用来自 Node.js 的核心 net 模块编写一个简单的端口扫描器。我的代码出现“回调已被调用”错误。你能发现错误来自哪里吗?以下是我的代码:

const net = require('net')
const async = require('async')

function findPortStatus(host, port, timeout, cb) {

  const socket = new net.Socket()

  socket.setTimeout(timeout, () => {
    // couldn't establish a connection because of timeout
    socket.destroy()
    return cb(null, null)
  })

  socket.connect(port, host, () => {
    // connection established
    return cb(null, port)
  })

  socket.on('error', (err) => {
    // couldn't establish a connection
    return cb(null, null)
  })
}

const funcs = []

for (let port = 0; port <= 80; port++) {
  funcs.push(function(callback) {
    findPortStatus('192.30.253.112', port, 4000, (err, port) => {
      if (!err) {
        return callback(null, port)
      }
    })
  })
}

async.parallel(funcs, (err, ports) => {
  if (err) {
    console.error(err.message)
  } else {
    for (let port of ports) {
      if (port) {
        console.log(port)
      }
    }
  }
})

【问题讨论】:

    标签: node.js asynchronous


    【解决方案1】:

    不确定这是否相关,但您确实应该在调用回调时将 something 传递给回调。 null,null 对于调试不是很有用。我建议您的上下文中的timeout 事件可能不是错误,但它们提供了丰富的信息。您可以只使用cb(null, 'timeout')cb(null, {state: 'timedOut', port: port}) 或其他东西来更好地跟踪哪些有效,哪些无效。

    不过,您的实际错误最有可能出现在您的套接字在连接事件已经成功之后发出错误或超时事件。断开连接等。如果您正在寻找的只是类似“ping”的功能(显然不仅仅是 ICMP),那么您可能应该在获得连接后立即关闭连接和/或删除其他事件侦听器作为连接侦听器的处理程序。

    最后,节点文档建议您不要直接调用socket.connect(),除非实现自定义套接字(看起来不像),而是使用net.createConnection();不确定这会对您有所帮助,但值得注意。

    【讨论】:

      【解决方案2】:

      看起来成功连接的套接字随后会超时(这是有道理的,因为您连接但随后对连接不执行任何操作,因此超时)。

      如果您在记录成功连接后从套接字断开连接,那么应该会清除错误。

      【讨论】:

        猜你喜欢
        • 2017-10-13
        • 1970-01-01
        • 2014-08-19
        • 2017-05-03
        • 1970-01-01
        • 2017-09-15
        • 1970-01-01
        • 2014-11-13
        • 2018-11-06
        相关资源
        最近更新 更多