Отправлять команды через сокет, но каждый раз ждать ответа (Node.js) - PullRequest
2 голосов
/ 10 августа 2011

Мне нужно отправить несколько команд через telnet на сервер. Если я попытаюсь отправить их без задержки между каждой командой, сервер взбесится:

var net = require('net');
var conn = net.createConnection(8888, 'localhost');
conn.on('connect', function() {
    conn.write(command_1);
    conn.write(command_2);  
    conn.write(command_3);
    //...
    conn.write(command_n);
})

Я полагаю, что серверу нужно некоторое время, чтобы ответить на команду n , прежде чем я отправлю ему команду n + 1 . Один из способов - записать что-нибудь в журнал и подделать «wait»:

var net = require('net');
var conn = net.createConnection(8888, 'localhost');
conn.on('connect', function() {
    console.log('connected to server');
    console.log('I'm about to send command #1');
    conn.write(command_1);
    console.log('I'm about to send command #2');
    conn.write(command_2);  
    console.log('I'm about to send command #3');
    conn.write(command_3);
    //...
    console.log('I'm about to send command #n');
    conn.write(command_n);
})

Возможно также, что conn.write() является асинхронным, и размещение одной команды за другой не гарантирует правильного порядка ??

В любом случае, каков правильный шаблон для обеспечения правильного порядка и достаточного времени между двумя последовательными командами для ответа сервера?

Ответы [ 2 ]

3 голосов
/ 10 августа 2011

Перво-наперво: если это действительно сервер telnet, то вы должны сделать что-то с установлением связи telnet (где параметры терминала согласовываются между узлами, это двоичные данные, которые вы можете видеть при открытии сокета).

Если вы не хотите вдаваться в это (это будет зависеть от ваших потребностей), вы можете проигнорировать переговоры и перейти прямо к делу, но вам придется читать эти данные и игнорировать их самостоятельно.

Теперь в вашем коде вы отправляете данные, как только сервер принимает соединение.Это может быть причиной ваших неприятностей.Вы не должны «ждать» ответа, ответ будет получен асинхронно благодаря nodejs :) Так что вам просто нужно отправить команды, как только вы получите «правильный» ответ от сервера (это на самом делеполезно, потому что вы можете увидеть, были ли какие-либо ошибки и т. д.).

Я пробовал этот код (на основе вашего) на устройстве, которое у меня под рукой, и имеет сервер telnet.Это сделает вход, а затем выход.Посмотрите, как события отправляются в соответствии с ответом сервера:

var net = require('net');
var conn = net.createConnection(23, '1.1.1.1');
var commands = [ "logout\n" ];
var i = 0;
conn.setEncoding('ascii');
conn.on('connect', function() {
    conn.on('login', function () {
        conn.write('myUsername\n');
    });
    conn.on('password', function () {
        conn.write('myPassword\n');
    });
    conn.on('prompt', function () {
        conn.write(commands[i]);
        i++;
    });
    conn.on('data', function(data) {
        console.log("got: " + data + "\n");
        if (data.indexOf("login") != -1) {
            conn.emit('login');
        }
        if (data.indexOf("password") != -1) {
            conn.emit('password');
        }
        if (data.indexOf(">#") != -1) {
            conn.emit('prompt');
        }
    });
});

Посмотрите, как команды находятся в массиве, где вы можете итеративно отправлять их (событие приглашения вызовет следующую команду).Таким образом, правильный ответ от сервера следующий запрос.Когда сервер отправляет (в данном случае) строку> #, отправляется другая команда.

Надеюсь, это поможет:)

0 голосов
/ 10 августа 2011

Порядок записи гарантирован.Однако:

  1. Вы должны подписаться на событие данных.conn.on ('data', function (data) {}) подойдет.
  2. Вы должны проверить возвращаемые значения записей - если запись не удалась, вы должны дождаться события "слив".Таким образом, вы должны проверить, действительно ли какая-либо запись не удалась, и если это так, то устранить проблему.Если это не так - тогда вы можете оставить текущий грязный раствор как есть.
  3. Вы должны проверить, поддерживает ли ваш сервер конвейеризацию запросов (отправка нескольких запросов без ожидания ответов).Если это не так - вы не должны отправлять следующий запрос до получения события данных после предыдущего.
  4. Вы должны убедиться, что отправляемые вами команды являются реальными командами telnet - telnet ожидает \ 0 байт после \ r\ n (см. RFC), поэтому некоторые серверы могут выходить из строя, если \ 0 отсутствует.

Итак:

var net = require('net');
var conn = net.createConnection(8888, 'localhost');
conn.on('connect', function() {
    console.log(conn.write(command_1) && 
    conn.write(command_2) &&
    conn.write(command_3) &&
    //...
    conn.write(command_n))

})
conn.on('data', function () {})

Если он пишет false - тогда вы должны ждать«утечка».Если пишет true - вы должны реализовать ожидание.Я не рекомендую основанное на событиях решение и предлагаю вместо этого использовать асинхронные модули или модули Step NPM.

...