Nodejs中关于net模块使用

Nodejs中关于net模块使用

《Nodejs实战》这本书,现在我看到第三章,前面总体的不错。 第三章中有段代码,纠结了一会,是关于net的,如下 QQ截图20140917160735.jpg 粗框里的这句是否已经算是connection事件了,然后下面细框中的又来了一个connect事件? 疑惑不觉,自己敲了一遍,发现确有问题,按照书上的代码根本无法触发connection事件了,去掉细框中的代码可以正常触发。 自己改了一下,如下 QQ截图20140917160510.jpg 不知道书上写得正确与否?还是我自己错了~


5 回复

在Node.js中,net 模块提供了用于创建服务器和客户端的功能。在这篇帖子中,我们将讨论 net 模块中 connectionconnect 事件的区别,并通过一些示例代码来说明它们的实际用法。

connection 事件 vs connect 事件

  • connection 事件:这是服务器端使用的事件。当有新的客户端连接到服务器时,服务器会触发 connection 事件。
  • connect 事件:这是客户端使用的事件。当客户端成功连接到服务器时,客户端会触发 connect 事件。

示例代码

服务器端代码

const net = require('net');

// 创建一个TCP服务器
const server = net.createServer((socket) => {
    console.log('Client connected');
    socket.on('end', () => {
        console.log('Client disconnected');
    });
});

server.listen(3000, () => {
    console.log('Server listening on port 3000');
});

客户端代码

const net = require('net');

const client = new net.Socket();
client.connect(3000, 'localhost', () => {
    console.log('Connected to server');
});

client.on('data', (data) => {
    console.log('Received: ' + data);
});

client.on('close', () => {
    console.log('Connection closed');
});

解释

在上述示例中:

  • 当客户端尝试连接到服务器时,客户端将触发 connect 事件,并打印 “Connected to server”。
  • 在服务器端,每当有一个新的客户端连接时,服务器将触发 connection 事件,并打印 “Client connected”。
  • 当客户端断开连接时,客户端将触发 close 事件,并打印 “Connection closed”。
  • 当服务器端接收到数据时,它将打印接收到的数据。

结论

根据上述代码,可以看出 connection 事件是在服务器端处理新连接的地方,而 connect 事件是在客户端成功建立连接时触发的。如果你在服务器端代码中看到类似 socket.on('connect', ...) 的代码,那么这可能是错误的,因为 connect 事件不应该在服务器端代码中出现。正确的做法是在客户端使用 connect 事件,在服务器端使用 connection 事件。


net.createServer带两个参数,optionsconnectionListener,两个都是可选的。而connectionListener是作为connection事件的监听器。

图1中,你怎么知道没有触发connection事件?只是没有触发connect而已。估计书上的是老版本写法。

新版本也有:

  • server.on(‘connection’, onconnection) 对应的是uv里面 uv_listen函数的第二个参数,是在uv层回调的,是在syscall(accept4)之后执行
  • client.on(‘connect’, onconnect)是在server端内部还有一个私有的onconnection函数,里面是client = new Socket(…),所以里面的connect事件是由nodejs触发的。
  • client的connect只有调用了Socket.prototype.connect方法后才执行(所以事件的名字才是connect),你可以顺着这个看:https://github.com/joyent/node/blob/master/lib/net.js#L837
  • 再看onconnection:https://github.com/joyent/node/blob/master/lib/net.js#L1272-L1301 ,在1288行直接new Socket了一个连接,但是这里只是把这个连接的句柄(fd)直接传给Socket用,所以后面没有调用connect(因为已经有句柄了嘛),最后在1300行(函数最后)直接把new的socket传出去给connection了。
  • 我木有说上面例子是对的,只是强调socket是有connect事件还有server的connection具体什么时候调用

根据你的描述,你在阅读《Node.js实战》时遇到了一些关于net模块的困惑。书中提到的代码片段可能有一些误解或错误。我们可以通过一段简单的示例代码来说明如何正确地使用net模块。

首先,你需要理解net模块中的connection事件和connect事件的区别:

  • connection事件是服务器端用来监听客户端连接的事件。
  • connect事件通常不会出现在服务器端代码中,它更常见于客户端,表示连接成功建立。

下面是一个简单的示例代码,展示如何使用net模块创建一个TCP服务器,并处理客户端连接:

const net = require('net');

// 创建一个TCP服务器
const server = net.createServer((socket) => {
    console.log('Client connected');
    
    // 监听数据接收事件
    socket.on('data', (data) => {
        console.log(`Received data: ${data.toString()}`);
    });
    
    // 监听断开连接事件
    socket.on('end', () => {
        console.log('Client disconnected');
    });
});

server.on('error', (err) => {
    console.error(`Server error: ${err.message}`);
});

// 监听connection事件
server.on('connection', (socket) => {
    console.log('New connection established');
});

// 监听端口
server.listen(3000, () => {
    console.log('Server is listening on port 3000');
});

在这个示例中:

  1. 使用net.createServer创建一个TCP服务器。
  2. 传入一个回调函数处理新连接的客户端。
  3. 在回调函数内部监听dataend事件。
  4. 使用server.on('connection', callback)来监听新的连接。

对于客户端代码,你可以这样实现:

const net = require('net');

const client = new net.Socket();

client.connect(3000, '127.0.0.1', () => {
    console.log('Connected to server');
    client.write('Hello, server!');
});

client.on('data', (data) => {
    console.log(`Server responded with: ${data.toString()}`);
    client.destroy(); // 结束连接
});

client.on('close', () => {
    console.log('Connection closed');
});

在这个客户端代码中:

  1. 使用net.Socket()创建一个新的Socket对象。
  2. 调用client.connect(port, host, callback)连接到服务器。
  3. 监听data事件以接收服务器响应的数据。
  4. 监听close事件以确定连接何时关闭。

希望这些示例代码能帮助你更好地理解net模块的使用方法。

回到顶部