通过套接字发送命令,但每次都等待响应(Node.js)

时间:2011-08-09 22:37:51

标签: sockets asynchronous node.js telnet

我需要通过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 + 1 之前需要一些时间来响应命令 n 。一种方法是在日志中写入内容并伪造“等待”:

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 个答案:

答案 0 :(得分:3)

首先要做的事情是:如果这真的是一个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');
        }
    });
});

查看命令在数组中的位置,您可以在其中迭代发送它们(提示事件将触发下一个命令)。因此,服务器的正确响应是下一个提示。当服务器发送(在这种情况下)字符串>#发送另一个命令时。

希望有所帮助:)

答案 1 :(得分:0)

保证写入顺序。但是:

  1. 您必须订阅数据事件。 conn.on('data',function(data) {})会做的。
  2. 您必须检查写入的返回值 - 如果写入 失败,你必须等待'排水'事件。所以你应该检查一下 写真的失败,如果确实失败,那么解决问题。如果它 没有 - 那么你可以保持现有的脏解决方案。
  3. 您 必须检查您的服务器是否支持请求piplining(发送 多个请求,无需等待响应)。如果没有 - 您不得在之后收到数据事件之前发送下一个请求 上一个。
  4. 您必须确保您发送的命令是真正的telnet命令 - telnet在\ r \ n之后需要\ 0字节(请参阅RFC),因此如果\ 0不存在,某些服务器可能会发生故障。
  5. 所以:

    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 () {})
    

    如果写错了 - 那么你必须等待'排水'。如果写得正确 - 你必须实现等待。我不鼓励基于事件的解决方案,并建议改为使用异步或步骤NPM模块。