我编写了以下函数:

  let responses = {}
  let socks = {}
  module.ping = function (port, address) {
    //console.log(`Ping function was called - ${address} ${port}`)
    if (socks[`${address}:${port}`]) {
      //console.log("Using existing socket")
      responses[`${address}:${port}`] = false
      sock = socks[`${address}:${port}`]
      sock.write('PING\n')
      console.log(`Sent PING to ${address} ${port}`)
    }
    else {
      sock = new net.Socket();
      responses[`${address}:${port}`] = false
      sock.connect(port, address, async function() {
        sock.write('PING\n')
        console.log(`Sent PING to ${address} ${port}`)
      });

      // Response listeners
      sock.on('data', function(data) {
        clean_data = data.toString().replace(/\n/g, '').replace(/\r/g, '')
        console.log(`[${sock.remoteAddress}:${sock.remotePort}] Received ${clean_data}`)
          if (clean_data == 'PONG') {
            //console.log(`[${sock.remoteAddress}:${sock.remotePort}] Received PONG`)
            //sock.end()
            //delete socks[`${address}:${port}`]
            responses[`${sock.remoteAddress}:${sock.remotePort}`] = true
          }
        }
      });
      sock.on('error', function(error) {
        if (sock.remoteAddress) {
          responses[`${sock.remoteAddress}:${sock.remotePort}`] = false
        }
        sock.destroy()
        delete socks[`${address}:${port}`]
      });

      // Add to list of sockets
      if (sock) {
        socks[`${address}:${port}`] = sock
      }
    }
  }
另一方面,我有一个监听的TCP服务器,该服务器简单地以“PONG\n”响应。当我尝试一台主机时,会得到预期的输出:
module.ping(1337, 10.0.0.100)
await delay(5000) // Custom function
module.ping(1337, 10.0.0.100)

但是,当我尝试击中多个主机时:
module.ping(1337, 10.0.0.100)
module.ping(1337, 10.0.0.200)
await delay(5000) // Custom function
module.ping(1337, 10.0.0.100)
module.ping(1337, 10.0.0.200)

在我看来,我添加的“数据”事件监听器以某种方式绑定(bind)到代码中的错误地址,但是我看不到哪里。如果我将更多主机添加到列表中,则发送PING的最后一台主机是所有PONG都标记为其中一部分的主机。

最佳答案

首先,我没有看到sock变量的声明,这意味着它在某个较高的范围内,并且在正在进行的不同异步操作之间被错误地混淆或删除。

在本地声明该变量,以便每次使用它都是一个单独的变量,并且一个异步操作不会覆盖您用于另一操作的变量。所有变量,非故意用于更高范围和共享的变量,都必须在本地声明。

我不知道这是否是唯一的问题,但这是一个问题。例如,如果您连续两次调用.ping()并必须创建两个新的套接字,则第二个套接字将在sock成功导致您将PING发送到错误的.connect()之前覆盖sock变量,这正是诊断日志所显示的内容。

关于javascript - 获取有关数据响应的TCP套接字特定数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58515040/

10-09 07:26
查看更多