node.js - 多次写入时 Node 网络数据合并

标签 node.js sockets

我正在使用 Node net。

当客户端多次写入 feed 时,服务器端收到 1 个数据。

var net           = require('net');

// SERVER SIDE
var net_port   = 8080; // node net port
var server = net.createServer(function(connection){
   connection.on('data', function(data){
          var str = data.toString();
          console.log("Received, Length: "+str.length); // IT SHOULD be 25 in length
    });
   connection.pipe(connection);
});

server.listen(net_port, function() { 
   console.log('server is listening');
});
// SERVER CODE NED

//### 客户端

var client = net.connect({port: 8080}, function() {
   console.log('connected to server!');  
});


string = "acdefghijklmnopqrstuvwxyz"; // 25 char
setInterval(function(){
    client.write(string);
    client.write(string);
},1);
setInterval(function(){
    client.write(string);
    client.write(string);
},1);

发送长度为25的字符串,但收到时输出为

Received, Length: 25
Received, Length: 25
Received, Length: 75  // merged 3 data
Received, Length: 100 // merged 4 data
Received, Length: 25
Received, Length: 50 // merge 2 times
Received, Length: 75
Received, Length: 25
Received, Length: 25
Received, Length: 25
Received, Length: 100

实际上,在我的实际代码中,我不能使用 split 字符串,因为如果客户端发送 String length 100 4 次。所以服务器收到了

Received, Length: 100
Received, Length: 220
Received, Length: 80

如何强制 Node Net 发送和接收实际数据。

fiddle :https://www.mycompiler.io/view/BJGjA87

最佳答案

net.createServer创建一个 TCP 服务器。 TCP 套接字是基于流的,而不是基于数据报的。它们没有消息边界的概念:一切都只是一个连续的字节流,没有标记来区分哪些片段是一起发送的,哪些是单独发送的。如果要在通过 TCP 套接字发送的消息之间建立边界,则必须自己描绘它们:通过假设每条消息必须具有固定的字节长度,或者通过引入标记来确定一个消息的结束位置和另一个消息的开始位置。

作为示例,下面是对服务器的简单修改,它使用 RFC 7464 中定义的 json-seq 格式。为此。从长远来看,您可以考虑使用 ws 等库将其改为 WebSocket 服务器。 。它可能比下面的代码更健壮;这主要只是一个演示。

var net = require('net');

var server = net.createServer(function (connection) {
    var buffer = '';
    
    function receivedMessage(value) {
        console.log('received: ' + JSON.stringify(value));
    }
    
    function protocolError() {
        console.log('protocol error');
        connection.close();
    }
    
    function parseMessages(buf) {
        console.log('parsing ' + buf.length + ' code units worth of messages');
        if (buf.substring(0, 1) !== '\x1e') {
            protocolError();
            return;
        }
        var m, rx = /\x1e([^\x1e]*)/g;
        while (m = rx.exec(buffer)) {
            if (m[1] === '')
                continue;
            try {
                var value = JSON.parse(m[1]);
            } catch (e) {
                if (e instanceof SyntaxError)
                    continue;   // RFC 7464 §2.3
                throw e;
            }
            receivedMessage(value);
        }       
    }
    
    connection.on('data', function (data) {
        buffer += data.toString('utf8');
        console.log(buffer.length + ' code units in the buffer');
        var lastRS = buffer.lastIndexOf('\x1e');
        if (lastRS === 0)
            return;
        var fullMessages = buffer.substring(0, lastRS);
        buffer = buffer.substring(lastRS, buffer.length);
        parseMessages(fullMessages);
        try {
            var value = JSON.parse(buffer);
        } catch (e) {
            if (e instanceof SyntaxError)
                return;  // maybe just truncated; defer error until later
            throw e;
        }
        receivedMessage(value);
        buffer = '';
    });

    connection.on('close', function () {
        console.log('closed');
        parseMessages(buffer);
    });
});

server.listen(8080, function() { 
    console.log('server is listening');
});

这是一个经过适当修改的客户端:

var net = require('net');

var client = net.connect({port: 8080}, function() {
   console.log('connected to server!');  
});

function sendMessage(value) {
    client.write(Buffer.from('\x1e' + JSON.stringify(value) + '\n', 'utf8'));
}

string = 'acdefghijklmnopqrstuvwxyz';

setInterval(function(){
    sendMessage(string);
    sendMessage(string);
}, 1);

setInterval(function(){
    sendMessage(string);
    sendMessage(string);
}, 1);

关于node.js - 多次写入时 Node 网络数据合并,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69167144/

相关文章:

javascript - 在 node.js 中 `module` 总是一个对象吗?

node.js - Nodejs 类验证器验证对象数组

node.js - skrill POST 状态响应为空, Node 为 Express

java - 关于 ServerSocket,需要澄清

iphone - 解析 NSNetService 时出错

node.js - 给所有用户的 GCM 消息(无主题)

node.js - 带有 primeng 404 问题的 angular-cli@webpack

java - 有没有办法将 SSLContext 与 ServerSocketChannel 一起使用?

c# - 使用套接字传输文件

.net - 将套接字排序为客户端对象