Получение данных сокета TCP по данным ответа - PullRequest
1 голос
/ 23 октября 2019

Я написал следующую функцию:

  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)

Отправлено PING на 10.0.0.100 1337

[10.0.0.100:1337] Получено PONG

Отправлено PING на 10.0.0.100 1337

[10.0.0.100:1337] Получено PONG

Однако, когда я пытаюсь поразить несколько хостов:

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)

Отправлено PING на 10.0.0.100 1337

Отправлено PING на 10.0.0.200 1337

[10.0.0.200:1337] Получено PONG

[10.0.0.200:1337] Получено PONG

Отправлено PING на 10.0.0.100 1337

Отправлено PING на 10.0.0.200 1337

[10.0.0.200:1337] Получено PONG

[10.0.0.200:1337] Получено PONG

Мне кажется, что прослушиватель событий для "данных", который я добавил, каким-то образом привязан к неверному адресу в моем коде, однако я не могу 'не вижу где. Если я добавлю больше хостов в список, последним хостом с отправленным PING будет тот, для которого все PONG помечены как часть.

1 Ответ

2 голосов
/ 23 октября 2019

Для начала, я не вижу объявления для переменной sock, что означает, что она находится в какой-то более высокой области видимости и ошибочно запутывается или разбивается между различными асинхронными операциями, которые выполняются обеими.

Объявите эту переменную локально, чтобы каждое ее использование было отдельной переменной, и одна асинхронная операция не будет перезаписывать ту, которую вы использовали для другой операции. ВСЕ переменные, не предназначенные специально для того, чтобы иметь более широкую область применения и совместно используемые, ДОЛЖНЫ быть объявлены локально.

Я не знаю, является ли это единственной проблемой здесь, но это проблема здесь. Например, если вы вызываете .ping() два раза подряд и должны создать два новых сокета, второй перезапишет переменную sock до того, как .connect() удастся заставить вас отправить PING на неправильный sock, чтоэто именно то, что показывают ваши диагностические журналы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...