多个套接字覆盖自身
Posted
技术标签:
【中文标题】多个套接字覆盖自身【英文标题】:Multiple sockets override itself 【发布时间】:2018-08-11 16:39:54 【问题描述】:我的代码
我想与 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
【问题讨论】:
尝试用一个实例运行 2 个节点进程,而不是在一个进程中运行 2 个实例。检查问题是来自您的代码还是人才阻止了用户 她自己?怎么看出是女的?我总是虽然它是男性:| @Red: 我知道我的英语不是最好的 :D @AmitWagner:如果我尝试使用它工作的每个实例来连接进程。但是一个实例每次都运行良好。我没有 3 个实例... 在您的第一个和第二个示例中,您有不同的 cardinals 。你能试着把工作的红衣主教放2个实例吗 【参考方案1】:根据您的错误,您的第二个实例未发送正确的登录信息:
错误 id=520 msg=invalid\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
。
【讨论】:
以上是关于多个套接字覆盖自身的主要内容,如果未能解决你的问题,请参考以下文章
套接字 IO:如何定义断开连接的套接字 id(当多个选项卡时)?