5

我在 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”现在由服务器和客户端打印。

4

5 回答 5

4

我想你正在寻找这个:socket.unref()。

从 Node.js 文档(https://nodejs.org/api/net.html#net_socket_unref):

socket.unref()#

如果这是事件系统中唯一的活动套接字,则在套接字上调用 unref 将允许程序退出。如果套接字已经是 unrefd,再次调用 unref 将无效。

于 2015-07-30T05:07:20.370 回答
2

前段时间在改进node-cubrid模块的测试套件时,我遇到了同样的问题。在所有测试都通过后,nodeunit 进程没有退出,因为 node-cubridconnection.end()在超时发生时用来关闭客户端套接字,就像你做的那样。

然后我替换 connection.end()connection.destroy()一种更简洁的方法,以确保套接字真正关闭而不实际终止正在运行的进程,我认为这是比上述建议更好的解决方案process.exit()。因此,在您的客户端代码上下文中,我会这样做:

process.stdin.on('data', function (data) {
    if ((new String(data)).toLowerCase() === 'exit') {
       connection.destroy();
    }
    else {
       connection.write(data);
    }
});

根据Node.js 文档

socket.destroy()

确保此套接字上不再发生 I/O 活动。仅在出现错误时才需要(解析错误左右)。

于 2013-07-16T02:21:31.120 回答
0

我怀疑这if ((new String(data)).toLowerCase() === 'exit')是否成功,因为data很可能有一个尾随换行符(在您的服务器中,您trim()在进行比较之前,而不是在客户端中)。

如果这个问题解决了,你就会遇到一个逻辑问题:当得到“exit”时,你关闭了连接而不向服务器发送“exit”,因此寻找“exit”的服务器代码将永远不会执行。

于 2012-10-24T15:09:54.880 回答
0

在服务器中尝试事件:'close': http ://nodejs.org/api/net.html#net_event_close

于 2012-10-24T15:34:18.680 回答
0

您必须process.exit()仅将指令放在最后一个事件处理程序上。因此,在这种情况下,您必须将其放在客户端连接“关闭”事件处理程序中:

客户:

connection.on('close', function() {
    console.log('Connection closed');
    process.exit();
});
于 2012-10-25T07:28:31.587 回答