多个套接字覆盖自身

时间:2018-03-03 16:34:10

标签: javascript node.js sockets telnet

我的代码

我想与telnet控制台建立多重连接。该项目适用于Teamspeak和Teamspeak,只需与telnet通信即可。我是一个使用net lib创建telnet连接作为套接字的对象。如果我们只有一个实例连接所有工作正常,我通过telnet连接返回服务器列表。但如果我有两个例子他说invalid loginname or password。登录信息是正确的,他也尝试只连接到一台服务器。

我的班级:

/*
    Teamspeak query client class
    @instance: Instance object of the teamspeak query client
*/
function TeamspeakQueryClient(instance) {
    events.EventEmitter.call(this);

    var $this = this,
        socket = net.connect(instance.port, instance.ip),
        reader = null,
        skipLines = -2,
        queue = [ ],
        executing = null,
        server = null;

    this.Type = 'Unknown';
    this.Id = null;
    this.Connected = false;
    this.Banned = false;

    /*
        Socket settings
    */
    socket.setKeepAlive(true, 60000);

    /*
        Socket connect to the teamspeak instance
    */
    socket.on("connect", function() {
        reader = LineInputStream(socket);
        reader.on("line", function(line) {
            var s = line.trim();
            console.log(line);

            // Skipp the first lines
            if(skipLines < 0){
                if(line === 'TS3') {
                    this.Type = 'Teamspeak';
                };

                skipLines++;

                if(skipLines === 0) {
                    checkQueue();

                    if(server === null) {
                        $this.SendCommand("login", {client_login_name: instance.client, client_login_password: instance.password}, function(err, response, rawResponse) {
                            console.log(err);
                            if(err === null) {
                                if(err.id === 3329) {
                                    $this.Banned = true;
                                };

                                $this.CloseSocket();
                            } else {
                                $this.SendCommand("serverlist", null, function(err, response, rawResponse){
                                    console.log(response);
                                    if(response[0] === undefined) {
                                        console.log('1 server');
                                    } else {
                                        console.log('mehrere server');
                                    };
                                    //console.log(rawResponse);
                                    /*cl.send("clientlist", function(err, response, rawResponse){
                                        console.log(util.inspect(response));
                                    });*/
                                });
                            };
                        });
                    } else {
                        console.log(server);   
                    };
                };

                return;
            };

            // Parse server request
            var response = undefined;
            if(s.indexOf("error") === 0){
                response = parseResponse(s.substr("error ".length).trim());
                executing.error = response;
                if(executing.error.id === 0) delete executing.error;
                if(executing.cb) executing.cb.call(executing, executing.error, executing.response,
                executing.rawResponse);
                executing = null;
                checkQueue();
            } else if(s.indexOf("notify") === 0){
                s = s.substr("notify".length);
                response = parseResponse(s);
                $this.emit(s.substr(0, s.indexOf(" ")), response);
            } else if(executing) {
                response = parseResponse(s); 
                executing.rawResponse = s;
                executing.response = response;
            };
        });

        $this.emit("connect");
    });

    /*
        Socket error
    */
    socket.on("error", function(err){
        log.LogLine(1, 'TeamspeakQueryClient: We got a error');
        log.LogLine(1, 'Message: '+err);
        $this.emit("error", err);
    });

    /*
        Socket close
    */
    socket.on("close", function(){
        log.LogLine(3, 'TeamspeakQueryClient: Socket from '+instance.alias+' closeing...');
        $this.emit("close", queue);
    });

    /*
        Function to send a custom command to the telnet console
    */
    TeamspeakQueryClient.prototype.SendCommand = function SendCommand() {
        var args = Array.prototype.slice.call(arguments);
        //console.log(args);
        var options = [], params = {};
        var callback = undefined;
        var cmd = args.shift();
        args.forEach(function(v){
            if(util.isArray(v)){
                options = v;
            } else if(typeof v === "function"){
                callback = v;
            } else {
                params = v;
            }
        });
        var tosend = tsescape(cmd);
        options.forEach(function(v){
            tosend += " -" + tsescape(v);
        });
        for(var k in params){
            var v = params[k];
            if(util.isArray(v)){ // Multiple values for the same key - concatenate all
                var doptions = v.map(function(val){
                    return tsescape(k) + "=" + tsescape(val); 
                });
                tosend += " " + doptions.join("|");
            } else {
                tosend += " " + tsescape(k.toString()) + "=" + tsescape(v.toString());
            }
        }
        queue.push({cmd: cmd, options: options, parameters: params, text: tosend, cb: callback});
        if(skipLines === 0) checkQueue();
    };

    /*
        Function to close the socket
    */
    TeamspeakQueryClient.prototype.CloseSocket = function CloseSocket() {
        socket.destroy();
        $this.emit("close");
    };

    /*
        Function to parse a string to a object
        @s: String of the object that will be parsed
        @return: Object of the parsed string
    */
    function parseResponse(s){
        var response = [];
        var records = s.split("|");

        response = records.map(function(k){
            var args = k.split(" ");
            var thisrec = { };
            args.forEach(function(v) {
                if(v.indexOf("=") > -1) {
                    var key = tsunescape(v.substr(0, v.indexOf("=")));
                    var value = tsunescape(v.substr(v.indexOf("=")+1));
                    if(parseInt(value, 10) == value) value = parseInt(value, 10);
                    thisrec[key] = value;
                } else {
                    thisrec[v] = "";
                };
            });
            return thisrec;
        });

        if(response.length === 0) {
            response = null;
        } else if(response.length === 1) {
            response = response.shift();
        };

        return response;
    };

    /*
        Function to write commands into the socket
    */
    function checkQueue() {
        if(!executing && queue.length >= 1){
            executing = queue.shift();
            socket.write(executing.text + "\n");
        };
    };

    /*
        Function to escape a telnet string
        @s: String that want to be escaped
        @return: The escaped string
    */
    function tsescape(s) {
        return s
            .replace(/\\/g, "\\\\")
            .replace(/\//g, "\\/")
            .replace(/\|/g, "\\p")
            .replace(/\n/g, "\\n")
            .replace(/\r/g, "\\r")
            .replace(/\t/g, "\\t")
            .replace(/\v/g, "\\v")
            .replace(/\f/g, "\\f")
            .replace(/ /g,  "\\s");
    };

    /*
        Function to unescape a telnet string
        @s: String that want to be unescaped
        @return: The unescaped string
    */
    function tsunescape(s) {
        return s
            .replace(/\\s/g,  " ")
            .replace(/\\p/g,  "|")
            .replace(/\\n/g,  "\n")
            .replace(/\\f/g,  "\f")
            .replace(/\\r/g,  "\r")
            .replace(/\\t/g,  "\t")
            .replace(/\\v/g,  "\v")
            .replace(/\\\//g, "\/")
            .replace(/\\\\/g, "\\");
    };
};

util.inherits(TeamspeakQueryClient, events.EventEmitter);

我如何打开课程

如果我调用示例,则一切正常,但示例二具有描述错误。

示例1:

 test1 = new TeamspeakQueryClient({
    "alias": "First-Coder Testinsance",
    "ip": "first-coder.de",
    "port": 10011,
    "client": "serveradmin",
    "password": "SECURE"
});

示例2:

 test1 = new TeamspeakQueryClient({
    "alias": "First Insance",
    "ip": "HIDDEN",
    "port": HIDDEN,
    "client": "serveradmin",
    "password": "SECURE"
});
test2 = new TeamspeakQueryClient({
    "alias": "Second Instance",
    "ip": "HIDDEN",
    "port": HIDDEN,
    "client": "serveradmin",
    "password": "SECURE"
});

截图

Picture of the error in the console

1 个答案:

答案 0 :(得分:0)

根据您的错误,您的第二个实例未发送正确的登录信息:

  

错误ID = 520 msg =无效\ sloginname \ sor \ spassword

显示的其他错误是由于您的代码无法正确处理错误。 例如:

socket.on("connect", function() {
...
    if(err === null) {
        if(err.id === 3329) {

如果err === null,为什么err会有一个元素id? 这很可能是代码错误,实际上你的意思是err !== null

$this.SendCommand("serverlist", null, function(err, response, rawResponse){
    console.log(response);
    if(response[0] === undefined) {

此错误会触发,因为未捕获(上面)上一个错误。

此时,客户端未登录(已授权)。

因此,当发送serverlist命令时,它会装配另一个错误。

此附加错误也无法处理,而是立即使用response