簡體   English   中英

Node.js網絡庫:從'data'事件中獲取完整數據

[英]Node.js net library: getting complete data from 'data' event

我四處搜索,要么找不到我要回答的確切問題,要么我需要有人向我解釋,就像我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]);
});

數據最終被分成兩個塊。 即使我將數據存儲在哈希中,並在讀取/ \\ 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);
        });
}

我最大的問題顯然是邏輯錯誤。 我要么等待開始回復的塊,要么等待結束它的塊。 我沒有把一切都保存在中間。

我想如果我想得到所有關於它的節點,我應該在每個完整的消息進入時觸發一個事件(以空白行開頭,在一行上以'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.
    });
}

我的問題是一個邏輯問題。 我要么尋找開始消息的塊,要么是結束消息的塊,而忽略它們之間的所有內容。 我猜想整個回復會以一兩個塊的形式出現。

這是從上面粘貼的工作代碼。 可能有更多的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);
        });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM