【问题标题】:Node.js net socketNode.js 网络套接字
【发布时间】:2021-12-03 23:34:34
【问题描述】:

我正在使用 net 模块创建侦听器,但遇到了一些问题。我试图让它等到它完成将“文本”写入客户端,然后客户端才能再次键入。如果我不这样做并且我坚持输入它只会让你能够在导致奇怪格式等的文本之间写入输入。

那么我怎样才能让它等到它被写入客户端呢?

代码:

const net = require('net');
const server = new net.Server();

server.on('connection', async function (socket) {
    console.log("Client connected!");

    socket.on('data', async function (data) {
        socket.setEncoding('utf8');
        let input = data.toString().replace(/(\r\n|\n|\r)/gm, "");
        if (input == "echo")
            socket.write("$ ");
        else
            socket.write("invalid command");
    });
});

server.listen(1337, function() {
    console.log("listening");
});

图片: https://imgur.com/a/lc21Y13

编辑: 这是在本地主机上,假设我将它托管在服务器上,所以会有更高的 ping 它更糟糕。

编辑: 这是托管在服务器上时的图片: https://imgur.com/a/LIKRRr9

编辑: 我试过用 SSH 代替 telnet 和 raw,现在得到了基本相同的结果。

图片: https://imgur.com/a/XJmpGSa

代码:

var fs = require('fs');
var username = null;
var ssh2 = require('ssh2');

new ssh2.Server({
    hostKeys: [fs.readFileSync('ssh.key')]
}, function (client) {
    console.log('Client connected!');

    client.on('authentication', function (ctx) {

        if (ctx.method !== 'password') return ctx.reject(['password']);

        if (ctx.method === 'password') {
            username = ctx.username;

            console.log(username);
            console.log(ctx.password);
            ctx.accept();
        }
        else {
            console.log("rejected.");
            ctx.reject();
        }

    }).on('ready', function () {
        console.log('Client authenticated!');

        client.on('session', function (accept, reject) {
            var session = accept();

            session.once('shell', function (accept, reject, info) {
                var stream = accept();

                stream.write("$ ");

                stream.on('data', function (data) {

                    var args = data.toString().split(" ");
                    console.log(args);

                    switch (args[0]) {
                        case "echo":
                            args.shift();
                            stream.write(args.join(" ") + "\r\n");
                            break;
                        case "whoami":
                            stream.write(username + "\r\n");
                            break;
                        case "exit":
                            stream.exit(0);
                            stream.end();
                            stream = undefined;
                            break;
                        default:
                            stream.stderr.write(args[0] + ": No such command!\r\n");
                            break;
                    }
                    if (typeof stream != 'undefined') {
                        stream.write("$ ");
                    }
                });
            });
        });
    }).on('end', function () {
        console.log('Client disconnected');
    });
}).listen(1337, function () {
    console.log('Listening on port ' + this.address().port);
});

【问题讨论】:

  • 不看任何代码就很难分辨。
  • 编辑了帖子。
  • 你如何想象一个阻止用户按键的程序?强大的力反馈?电击?
  • 我见过一些项目,当您输入垃圾邮件时它不会“出错”。我以为它一直等到它把数据写给用户,然后允许你再次在你的客户端中写,但我猜我错了。

标签: node.js sockets


【解决方案1】:

试试这个。这段代码所做的只是缓冲,直到从客户端接收到 \n 输入。

const net = require("net");
const readline = require("readline");

const execCommand = (command, args, socket) => {
  return new Promise((res, rej) => {
    setTimeout(() => {
      // to clear the terminal
      socket.write("\u001B[2J\u001B[0;0f");
      socket.write(
        `Executed command: ${command} with args: ${args} and result was: ${Math.random()}`
      );
      socket.write('\n>')
      res();
    }, 3000);
  });
};

const server = net.createServer((socket) => {
  socket.write("Connected");
  // nice prompt
  socket.write("\n>");

  const rl = readline.createInterface({
    input: socket,
    output: socket,
  });

  rl.on("line", (line) => {
    if (line.length === 0) {
      socket.write("No command to execute!");
      socket.write('\n>')
      return;
    }
    // destructuring command and args
    // E.g. command arg1 arg2 ....
    const [command, ...args] = line.split(" ");
    execCommand(command, args, socket);
  });
});

server.listen(1337, "127.0.0.1");

【讨论】:

  • 试过这个,结果基本一样。
  • 你是如何连接到这个服务器的?您可以通过使用 telnet 连接来测试它。喜欢来自命令提示符或终端的telnet localhost 1337
  • 使用 KiTTY 或 PuTTY
  • 我也在 localhost 上尝试过,结果更好,因为我接收数据的速度更快,但它仍然不时发生。
  • 你说的“结果更好”是什么意思?如果您使用我在上面评论中提到的 telnet,一旦建立连接,您可以输入多个字符,然后按 Enter。服务器应该回复您输入的所有字符。
猜你喜欢
  • 1970-01-01
  • 2013-03-18
  • 2015-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多