当前位置: 首页 > 面试题库 >

NodeJS:处理TCP套接字流的正确方法是什么?我应该使用哪个定界符?

董子航
2023-03-14
问题内容

从我的理解在这里,“V8拥有世代垃圾收集器。物件的移动风靡随机,节点不能得到一个指向原始字符串数据写入到插座。”
因此,我不应该将来自TCP流的数据存储在字符串中,特别是当该字符串变得大于Math.pow(2,16)字节时。(希望我到目前为止是..)

那么,处理来自TCP套接字的所有数据的最佳方法是什么?到目前为止,我一直在尝试_:_:_用作定界符,因为我认为它在某种程度上是唯一的,不会缠结其他事物。

将要收集的数据样本是 something_:_:_maybe a large text_:_:_ maybe tons of lines_:_:_more and more data

这是我尝试做的:

net = require('net');
var server = net.createServer(function (socket) {
    socket.on('connect',function() {
        console.log('someone connected');
        buf = new Buffer(Math.pow(2,16));  //new buffer with size 2^16
        socket.on('data',function(data) {
            if (data.toString().search('_:_:_') === -1) {    // If there's no separator in the data that just arrived...
                buf.write(data.toString());   // ... write it on the buffer. it's part of another message that will come.
            } else {        // if there is a separator in the data that arrived
                parts = data.toString().split('_:_:_'); // the first part is the end of a previous message, the last part is the start of a message to be completed in the future. Parts between separators are independent messages
                if (parts.length == 2) {
                    msg = buf.toString('utf-8',0,4) + parts[0];
                    console.log('MSG: '+ msg);
                    buf = (new Buffer(Math.pow(2,16))).write(parts[1]);
                } else {
                    msg = buf.toString() + parts[0];
                    for (var i = 1; i <= parts.length -1; i++) {
                        if (i !== parts.length-1) {
                            msg = parts[i];
                            console.log('MSG: '+msg);
                        } else {
                            buf.write(parts[i]);
                        }
                    }
                }
            }
        });
    });
});

server.listen(9999);

每当我尝试时console.log('MSG' + msg),它将打印出整个缓冲区,因此,看看是否有任何作用是没有用的。

如何正确处理这些数据?即使此数据不是面向行的,惰性模块也可以工作吗?是否有其他模块可以处理非面向行的流?


问题答案:

确实已经说过,还有很多工作要做,因为Node必须获取该缓冲区,然后将其推入v8
/将其转换为字符串。但是,在缓冲区上执行toString()并没有更好的效果。据我所知,目前还没有很好的解决方案,尤其是如果您的最终目标是找到一个字符串并胡闹的话。Ryan提到@nodeconf是需要完成工作的领域之一。

至于定界符,您可以选择任何您想要的。许多二进制协议选择包含固定的标头,这样您就可以将事物放到正常的结构中,而该结构通常包含一个长度。这样,您就可以分割一个已知的标头并获取有关其余数据的信息,而不必遍历整个缓冲区。使用这样的方案,可以使用以下工具:

  • 节点缓冲区-https: //github.com/substack/node-binary
  • node-ctype- https://github.com/rmustacc/node-ctype

顺便说一句,可以通过数组语法访问缓冲区,也可以使用.slice()将其分割。

最后,在这里检查:https :
//github.com/joyent/node/wiki/modules-找到一个解析简单tcp协议并且看起来做得很好的模块,并阅读一些代码。



 类似资料:
  • 问题内容: 我的Go服务器上有一个有效的TCP套接字设置。我接受传入连接,运行for循环并使用net.Conn.Read函数读取传入数据。 但这对我来说毫无意义。如何知道已收到完整的消息以便继续返回消息大小? 这是我目前的代码: 可以说我的应用程序发送的消息长度为6个字节(可以是任意大小)。怎么知道收到消息后才继续呢? 我的经验主要在于C#,所以Go在这里并不常见。对于我的C#应用​​程序,消息具

  • 问题内容: 我使用10gen的本机node.js驱动器将mongodb(2.2.2)与node.js一起使用。 起初一切顺利。但是当涉及到并发基准测试部分时,会发生很多错误。频繁进行1000次并发连接/关闭可能会导致mongodb拒绝任何进一步的请求,并出现以下错误: 另外,如果许多客户端在没有显式关闭的情况下关闭,则mongodb将花费几分钟的时间来检测并关闭它们。这也将导致类似的连接问题。(使

  • 我试试看。js与mongodb(2.2.2)一起使用本机节点。js drive by 10gen。 起初一切都很顺利。但在并发基准测试部分,出现了很多错误。频繁连接/关闭1000次并发可能会导致mongodb拒绝任何进一步的请求,错误如下: 此外,如果很多客户端在没有显式关闭的情况下关闭,mongodb需要几分钟来检测并关闭它们。这也会导致类似的连接问题。(使用/var/log/mongodb/m

  • 问题内容: 我正在使用Spring MVC在SQL Server数据库之上构建薄层。当我开始测试时,似乎不能很好地处理压力:)。我正在使用Apache Commons DBCP 来处理连接池和数据源。 当我第一次尝试同时建立约10-15个连接时,它曾经挂起,不得不重启服务器(对于开发人员,我正在使用Tomcat,但最终我将不得不在Weblogic上进行部署)。 这些是我的Spring bean定义

  • 问题内容: 任何人都可以澄清一下下面的过程是否是正确的处理流程流的方法,而没有任何流缓冲区已满和阻塞问题 我正在从Java程序中调用外部程序,正在使用ProcessBuilder来构建流程,执行之后 我正在使用一种方法来处理流程 在我的方法中,我试图处理流程流 readStream方法用于读取我的流文本。 问题答案: 不,那不是正确的方法。 首先,在某些系统上,您的代码将永远停留在调用中,因为该过

  • 考虑到我正在使用以下RESTful APIendpoint: /users/:显示所有用户 /users/$user_id/:显示特定用户 /users/$user_id/posts/:按用户显示所有帖子 /users/$user_id/posts/$post_id/:按用户显示特定帖子 这个数据模型中的约束:一篇文章总是有一个用户。 “处理嵌套资源”是指处理CRUD操作。 我应该在 /users