Nodejs中关于net模块使用
Nodejs中关于net模块使用
《Nodejs实战》这本书,现在我看到第三章,前面总体的不错。
第三章中有段代码,纠结了一会,是关于net的,如下
粗框里的这句是否已经算是connection事件了,然后下面细框中的又来了一个connect事件?
疑惑不觉,自己敲了一遍,发现确有问题,按照书上的代码根本无法触发connection事件了,去掉细框中的代码可以正常触发。
自己改了一下,如下
不知道书上写得正确与否?还是我自己错了~
在Node.js中,net
模块提供了用于创建服务器和客户端的功能。在这篇帖子中,我们将讨论 net
模块中 connection
和 connect
事件的区别,并通过一些示例代码来说明它们的实际用法。
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
带两个参数,options
和connectionListener
,两个都是可选的。而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具体什么时候调用