Node.jsnetworking库:从“数据”事件获取完整的数据

我四处搜寻,要么找不到确切的问题,要么我需要有人向我解释,就像我5。

基本上,我有一个使用networking库的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]); }); 

数据最终被分成两个部分。 即使我将数据存储在散列中,并在读取/ \ r \ nEND \ r \ n /分隔符时将第一部分追加到其余部分,也会丢失中间的大块。 如何正确地缓冲数据以确保从stream中获取完整的消息?

编辑:好的,这似乎是工作更好:

 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); }); } 

我最大的问题显然是一个逻辑错误。 我正在等待开始回复的块,或者结束它的块。 我没有保存所有的东西。

我想如果我想要得到所有的Node-ish,我应该在一个完整的消息进来的时候触发一个事件(以一个空行开始,以一行结尾为'END'),然后在那里进行处理。

你不应该对你收到的数据做任何事情,直到你收到结束事件。 结束callback意味着所有数据块已经通过stream发送到您的callback。 如果数据来自多个块,则需要在函数闭包中创build一个variables来存储这些数据。 大多数程序可以很好地忽略这个事实,因为数据通常会在一个块中出现。 但有时候并不是这样。 它甚至不一定取决于数据量。 如果您遇到这种情况,我创build了一个演示如何处理它的示例。 我基本上使用你的代码,但删除了所有的绒毛…这只是演示你需要收集所有的数据,并在其上工作的逻辑。

 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. }); } 

我的问题是一个逻辑问题。 我要么寻找开始消息的块,要么就是结束消息的块,而忽略其间的所有内容。 我猜想整个答复都会有一两个分组。

这是从上面粘贴的工作代码。 可能还有更多的Node-ish方法(我应该为每个信息块发出一个事件),但是除非有人在明天的这个时候发布更好的版本,否则我会将其标记为答案。

 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); }); }