Node.js踩坑之旅(一)

我作为一个初学者,在看书写代码的时候难免会遇到一些坑,我想把自己经历的大大小小的一些坑写出来。不仅提醒自己,也是给同处相同学习阶段的人的小小的分享。

这几天看了看node.js的net模块,看到了socket对象监听data事件以及socket对象的pipe方法。

我误以为pipe方法就是将socket对象监听data事件时返回的data数据写入文件。于是我写了如下代码:

let net = require('net');
let fs        = require('fs');
let tcpServer = net.createServer();

tcpServer.on('listening', ()=>{
    console.log('开始监听');
});

tcpServer.on('connection', (socket)=>{
    console.log('连接已建立' + '\n');
    tcpServer.getConnections((err, count)=>{
        if(err){
            console.warn(err);
        } else {
            console.log(`当前有${count}个连接`);
        }
    });
    let writeStream = fs.createWriteStream('./message.txt');
    socket.on('data', (data)=>{
        socket.pipe(writeStream);
    });
});

tcpServer.listen(2000);

上面的代码中我用net模块的createServer方法创建了一个TCP服务器,可以看到在socket对象对data事件的监听函数中,执行的是socket.pipe(writeStream);

当连接建立后,我在客户端键盘输入"12345"之后,在message.txt里写入的却是2334445555

而按多几个键之后则会出现达到监听器的最大上限和内存泄露的错误提示。

这一开始让我百思不得其解,明明我按的是"12345",为什么输出的文件中没有1?为什么有两个“3”,三个“4”和四个“5”?还有为什么按多几个键之后就会报错?

后来我注意到书上有这么一句话

可以利用socket对象的pipe方法将客户端发送的流数据书写到文件等其他目标对象中。

我突然意识到是不是直接使用pipe方法就可以了呢?于是我就把socket对象对data事件的监听去掉:

let net = require('net');
let fs        = require('fs');
let tcpServer = net.createServer();

tcpServer.on('listening', ()=>{
    console.log('开始监听');
});

tcpServer.on('connection', (socket)=>{
    console.log('连接已建立' + '\n');
    tcpServer.getConnections((err, count)=>{
        if(err){
            console.warn(err);
        } else {
            console.log(`当前有${count}个连接`);
        }
    });
    let writeStream = fs.createWriteStream('./message.txt');
    socket.pipe(writeStream);
});

tcpServer.listen(2000);

运行的结果一切都正常。

原来,pipe方法的实现本身就监听了dataend等事件。所以,当我按下"1"的时候,pipe方法才刚开始监听,自然"1"也就不会被写入到文件中,而我按下“2”之后,“2”被写入文件,而这时候又会多一条通往被写入文件的管道,同时也增加了一系列的监听函数。

于是我按下“3”的时候,“3”就会通过两个管道被写入文件,也就出现了两个“3”。而这时候,也会再多一条通往被写入文件的管道。

这就是之前种种奇怪现象的原因。当按的键足够多,达到系统默认的一个对象可以设置监听器的最大值时,就会报错。

你可能感兴趣的:(Node.js,Node.js,初学,踩坑)