重试时客户端连接未正确关闭

Posted

技术标签:

【中文标题】重试时客户端连接未正确关闭【英文标题】:Client connections not closed properly over retries 【发布时间】:2019-09-02 00:45:50 【问题描述】:

我有一个小型测试 telnet 客户端,需要对 android 设备执行身份验证。它工作正常,但是想了解该方法是否正确且不会导致内存泄漏。

我觉得这个脚本可能导致内存泄漏的原因是因为当连接建立时,我看到多个连接确认:

 node test.js
Connection refused, device not up yet..
Retrying..
Connection closed
CONNECTED TO: 127.0.0.1:5554
CONNECTED TO: 127.0.0.1:5554
Received: Android Console: Authentication required
Android Console: type 'auth <auth_token>' to authenticate
Android Console: you can find your <auth_token> in 
'/Users/testr/.emulator_console_auth_token'
OK

我希望看到的只是CONNECTED TO: 127.0.0.1:5554 的一个实例

我相信我在关闭旧连接的地方犯了一个错误,但无法理解在哪里。

如果服务器已启动:

在第一次尝试中,身份验证工作正常:

CONNECTED TO: 127.0.0.1:5554
Received: Android Console: Authentication required
Android Console: type 'auth <auth_token>' to authenticate
Android Console: you can find your <auth_token> in 
'/Users/testr/.emulator_console_auth_token'
OK

连接重试时:

Connection refused, device not up yet..
Retrying..
Connection closed
CONNECTED TO: 127.0.0.1:5554
CONNECTED TO: 127.0.0.1:5554
Received: Android Console: Authentication required
Android Console: type 'auth <auth_token>' to authenticate
Android Console: you can find your <auth_token> in 
'/Users/testr/.emulator_console_auth_token'
OK

const net = require('net');
const HOST = '127.0.0.1';
const Port = 5554;
let client = new net.Socket();


    // connection
     const conn = function Connect(Port) 
         client.connect(Port, '127.0.0.1', function () 
            console.log('CONNECTED TO: ' + '127.0.0.1' + ':' + Port);
             client.write('auth testcred');
        );
    ;

     // error handling
    client.on('error', function (error) 
        if (error.code === 'ECONNREFUSED') 
            console.log("Connection refused, device not up yet..");
            console.log("Retrying..");
            setTimeout(function() 
                conn(Port);
            , 10000);
        
    );

    // on response from server
    client.on('data', function(data) 
        console.log('Received: ' + data);
        client.destroy();
        client.removeAllListeners();
    );

    // on connection closure
    client.on('close', function() 
        console.log('Connection closed');
        client.destroy();
    );


     conn(Port);


我希望输出只返回一次CONNECTED TO: 127.0.0.1:5554,但我看到它打印的次数等于重试次数。

【问题讨论】:

【参考方案1】:

可能发生的事情是:

    您只有一个插槽,并且: 一次只能连接一个,但是: 您在套接字上注册了多个connectListeners。每次您拨打connect() 时都会注册一个新的,而且列表会越来越长。

参考。 docs:

connectListener socket.connect() 方法的公共参数。将添加一次作为“连接”事件的侦听器。

在这种情况下,文档给出的建议(使用net.createConnection() 打开套接字)可能是合适的。与其给client 赋予较长的生命周期,不如在每次要开始新连接时更换它。

【讨论】:

谢谢@greeble31,这很有意义,我要修改我的方法。非常感谢,干杯!

以上是关于重试时客户端连接未正确关闭的主要内容,如果未能解决你的问题,请参考以下文章

grpc-java:正确处理客户端重试以进行服务流调用

socket.io 客户端持续重试到无法访问的主机

如何正确关闭客户端代理(现有连接被远程主机强行关闭)?

系统网页提示Wedstorkte未建立连接

Spring kafka记录标题未正确填充

校园网inode连接网络之后直接认证无响应,5分钟后重试