cod*_*ero 7 javascript tcp node.js node.js-stream
我四处寻找,要么找不到我想要回答的确切问题,要么我需要有人向我解释,就像我5岁.
基本上,我有一个使用Net库的Node.js脚本.我正在连接多个主机,发送命令和侦听返回数据.
var net = require('net');
var nodes = [
'HOST1,192.168.179.8',
'HOST2,192.168.179.9',
'HOST3,192.168.179.10',
'HOST4,192.168.179.11'
];
function connectToServer(tid, ip) {
var conn = net.createConnection(23, ip);
conn.on('connect', function() {
conn.write (login_string); // login string hidden in pretend variable
});
conn.on('data', function(data) {
var read = data.toString();
if (read.match(/Login Successful/)) {
console.log ("Connected to " + ip);
conn.write(command_string);
}
else if (read.match(/Command OK/)) { // command_string returned successful,
// read until /\r\nEND\r\n/
// First part of data comes in here
console.log("Got a response from " + ip + ':' + read);
}
else {
//rest of data comes in here
console.log("Atonomous message from " + ip + ':' + read);
}
});
conn.on('end', function() {
console.log("Lost conncection to " + ip + "!!");
});
conn.on('error', function(err) {
console.log("Connection error: " + err + " for ip " + ip);
});
}
nodes.forEach(function(node) {
var nodeinfo = node.split(",");
connectToServer(nodeinfo[0], nodeinfo[1]);
});
Run Code Online (Sandbox Code Playgroud)
数据最终被分成两个块.即使我将数据存储在哈希中,并在读取/\r \nEND\r \n/delimiter时将第一部分附加到余数,但是中间缺少一个块.如何正确缓冲数据以确保从流中获取完整的消息?
编辑:好的,这似乎更好:
function connectToServer(tid, ip) {
var conn = net.createConnection(23, ip);
var completeData = '';
conn.on('connect', function() {
conn.write (login_string);
});
conn.on('data', function(data) {
var read = data.toString();
if (read.match(/Login Successful/)) {
console.log ("Connected to " + ip);
conn.write(command_string);
}
else {
completeData += read;
}
if (completeData.match(/Command OK/)) {
if (completeData.match(/\r\nEND\r\n/)) {
console.log("Response: " + completeData);
}
}
});
conn.on('end', function() {
console.log("Connection closed to " + ip );
});
conn.on('error', function(err) {
console.log("Connection error: " + err + " for ip " + ip);
});
}
Run Code Online (Sandbox Code Playgroud)
我最大的问题显然是逻辑错误.我要么等待开始回复的块,要么等待结束它的块.我没有把一切都保存在中间.
我想如果我想得到所有关于它的节点,我应该在每个完整的消息进入时触发一个事件(以空白行开头,在一行上以'END'结尾),并在那里进行处理.
在收到结束事件之前,您不应对接收到的数据做任何事情。结束回调意味着所有数据块都已通过流发送到您的回调。如果数据包含多个块,则需要在函数闭包内创建一个变量以存储该数据。忽略这一事实,大多数程序都可以正常工作,因为数据通常是成块出现的。但有时并非如此。它甚至不一定取决于数据量。如果您遇到这种情况,我创建了一个示例来演示如何处理它。我基本上使用了您的代码,但是删除了所有的绒毛...这只是演示了收集所有数据并进行处理所需的逻辑。
function connectToServer(tid, ip) {
var conn = net.createConnection(23, ip);
var completeData = '';
conn.on('connect', function() {
conn.write (login_string); // login string hidden in pretend variable
});
conn.on('data', function(data) {
completeData += data;
var dataArray = completeData.split('your delimiter');
if(dataArray.size > 1) { //If our data was split into several pieces, we have a complete chunk saved in the 0th position in the array
doWorkOnTheFirstHalfOfData(dataArray[0]);
completeData = dataArray[1];// The second portion of data may yet be incomplete, thise may need to be more complete logic if you can get more than one delimeter at a time...
}
});
conn.on('end', function() {
//do stuff with the "completeData" variable in here.
});
}
Run Code Online (Sandbox Code Playgroud)
我的问题是一个逻辑问题。我要么寻找开始消息的块,要么寻找结束消息的块,并忽略中间的所有内容。我猜想整个回复都会分成一两块。
这是从上面粘贴的工作代码。可能有一种更节点化的方法来做到这一点(我真的应该为每个信息块发出一个事件),但我会将其标记为答案,除非有人在明天这个时候发布更好的版本。
function connectToServer(tid, ip) {
var conn = net.createConnection(23, ip);
var completeData = '';
conn.on('connect', function() {
conn.write (login_string);
});
conn.on('data', function(data) {
var read = data.toString();
if (read.match(/Login Successful/)) {
console.log ("Connected to " + ip);
conn.write(command_string);
}
else {
completeData += read;
}
if (completeData.match(/Command OK/)) {
if (completeData.match(/\r\nEND\r\n/)) {
console.log("Response: " + completeData);
}
}
});
conn.on('end', function() {
console.log("Connection closed to " + ip );
});
conn.on('error', function(err) {
console.log("Connection error: " + err + " for ip " + ip);
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9470 次 |
| 最近记录: |