我在Node.js中构建了一个简单的TCP服务器和一个简单的TCP客户端
现在,当客户端向服务器发送“exit”时,连接成功关闭。服务器从套接字列表中删除套接字并发送“Bye bye!”给客户。
客户端上的连接也已关闭,但应用程序仍在等待其他输入,因此它不会死,我不得不键入CTRL + C.
我尝试在连接关闭后添加process.exit()
,但它不起作用:
客户代码:
var net = require('net'),
config = require(__dirname + '/config.json'),
connection = net.createConnection(config.port, config.host);
connection.setEncoding('utf8');
connection.on('connect', function () {
console.log('Connected');
});
connection.on('error', function (err) {
console.error(err);
});
connection.on('data', function (data) {
console.log('» ' + data);
});
connection.on('close', function() {
console.log('Connection closed');
});
process.stdin.on('data', function (data) {
if ((new String(data)).toLowerCase() === 'exit') {
connection.end();
process.exit();
}
else {
connection.write(data);
}
});
process.stdin.resume();
服务器代码:
var server = require('net').createServer(),
config = require(__dirname + '/config.json'),
sockets = [];
server.on('connection', function (socket) {
socket.setEncoding('UTF-8');
socket.on('data', function (data) {
console.log('Received data: ' + data);
if (data.trim().toLowerCase() === 'exit') {
socket.write("Bye bye!\n");
socket.end();
}
else {
sockets.forEach(function (client) {
if (client && client != socket) {
client.write(data);
}
});
}
});
socket.on('close', function () {
console.log('Connection closed');
sockets.splice(sockets.indexOf(socket), 1);
console.info('Sockets connected: ' + sockets.length);
});
sockets.push(socket);
});
server.on('listening', function () {
console.log('Server listening');
});
server.on('close', function () {
console.log('Server is now closed');
});
server.on('error', function (err) {
console.log('error:', err);
});
server.listen(config.port);
修改
我在“关闭”事件处理程序中添加了一个客户端连接。因此,字符串“Connection closed”现在由服务器和客户端打印。
答案 0 :(得分:4)
我认为你正在寻找这个:socket.unref()。
来自Node.js文档(https://nodejs.org/api/net.html#net_socket_unref):
socket.unref()#
如果这是事件系统中唯一的活动套接字,则在套接字上调用unref将允许程序退出。如果套接字已经unfd,则再次调用unref将无效。
答案 1 :(得分:2)
前段时间改进node-cubrid模块的测试套件时,我遇到了同样的问题。在所有测试都通过之后,nodeunit进程没有退出,因为node-cubrid在发生超时时使用connection.end()
关闭客户端套接字,就像你一样。
然后我replaced connection.end()
使用connection.destroy()
,这是一种更清晰的方法,可以确保套接字真正关闭而不会实际终止正在运行的进程,我认为,是比上面提到的process.exit()
更好的解决方案。因此,在您的客户端代码上下文中,我会这样做:
process.stdin.on('data', function (data) {
if ((new String(data)).toLowerCase() === 'exit') {
connection.destroy();
}
else {
connection.write(data);
}
});
<强> socket.destroy()强>
确保此套接字上不再发生I / O活动。仅在出现错误时才需要(解析错误等)。
答案 2 :(得分:0)
我怀疑if ((new String(data)).toLowerCase() === 'exit')
是否成功,因为data
很可能有一个尾随换行符(在您的服务器中,您在进行比较之前是trim()
,而不是在客户端中)。
如果修复了,你就会遇到一个逻辑问题:当你“退出”时你关闭连接而不向服务器发送“退出”,所以寻找“退出”的服务器代码永远不会执行。
答案 3 :(得分:0)
尝试使用事件:服务器中的“关闭”: http://nodejs.org/api/net.html#net_event_close
答案 4 :(得分:0)
您必须仅将process.exit()
指令放在最后一个事件处理程序上。因此,在这种情况下,您必须将其放在客户端连接“on close”事件处理程序中:
<强>客户端:强>
connection.on('close', function() {
console.log('Connection closed');
process.exit();
});