JS实现多Telnet连接至同一服务器报错,求解决方案
Telnet多连接脚本错误排查与优化方案
本人并非JS专家,还请见谅。我尝试编写JS脚本,实现从一台服务器通过Telnet协议与另一台服务器建立10个连接。以下是我的脚本:
const { readFileSync } = require('fs'); //const { Client } = require('telnet-client'); const { Telnet } = require('telnet-client'); const conn = (nb) => { const conn = new Telnet(); conn.on('ready', () => { console.log(`[${nb}]`, 'Client :: ready'); conn.shell((err, stream) => { if (err) { console.log(err); throw err; } stream.on('close', () => { console.log(`${nb}`, 'Stream :: close'); conn.end(); }).on('data', (data) => { console.log(`${nb}`, "OUTPUT: " + data); }); stream.end('sleep 600\n'); }); }).connect({ host: 'srvAP', port: 23, username: 'toto', password: 'toto' }); } Array.from(Array(10)).forEach(async(x, nb) => { let now = Date.now(); setTimeout(function() { console.log("Sleep ", nb); console.log(`${nb}`, "Run conn " + nb); conn(nb); console.log("Sleep end ", nb, Date.now() - now); }, nb * 750); });
运行时出现如下错误:
/exploit/tmp/SLE/poc_vega-ssh-load/node_modules/telnet-client/lib/index.js:130 return reject(new Error('Cannot connect')); ^ Error: Cannot connect at Socket.<anonymous> (/exploit/tmp/SLE/poc_vega-ssh-load/node_modules/telnet-client/lib/index.js:130:35) at Object.onceWrapper (node:events:627:28) at Socket.emit (node:events:513:28) at Socket._onTimeout (node:net:550:8) at listOnTimeout (node:internal/timers:559:17) at processTimers (node:internal/timers:502:7)
问题分析
- 连接超时:错误本质是连接超时,大概率是目标服务器Telnet服务限制了并发连接数,或者脚本没配置合理的超时时间,导致快速触发超时失败。
- 错误处理缺失:原脚本没有监听
error事件,连接失败直接抛出错误导致脚本崩溃,也没有重试逻辑。 - 异步逻辑冗余:用
forEach套setTimeout的写法不够直观,换成for循环+await更易维护。
修复与优化方案
1. 核心修复点
- 给Telnet连接添加超时配置,避免因默认超时过短导致连接失败;
- 新增
error事件监听,捕获连接失败并输出日志,防止脚本崩溃; - 简化异步流程,用
async/await控制连接创建的间隔,代码更清晰。
优化后的完整脚本
const { Telnet } = require('telnet-client'); // 创建单个Telnet连接的异步函数 async function createTelnetConn(connNum) { const telnetConn = new Telnet(); const connOpts = { host: 'srvAP', port: 23, username: 'toto', password: 'toto', timeout: 10000, // 设置10秒连接超时,可根据实际调整 negotiationMandatory: false // 部分服务器不需要协商,关闭可避免兼容性问题 }; // 监听连接就绪事件 telnetConn.on('ready', () => { console.log(`[${connNum}] 连接就绪`); // 获取shell并发送保持连接的命令 telnetConn.shell((err, stream) => { if (err) { console.error(`[${connNum}] 获取Shell失败:`, err); return; } // 监听流关闭事件 stream.on('close', () => { console.log(`[${connNum}] 连接流关闭`); telnetConn.end(); }); // 输出服务器返回内容 stream.on('data', (data) => { console.log(`[${connNum}] 服务器输出: ${data.toString().trim()}`); }); // 发送sleep命令保持连接600秒 stream.write('sleep 600\n'); }); }); // 监听连接错误事件 telnetConn.on('error', (err) => { console.error(`[${connNum}] 连接出错:`, err.message); }); // 监听连接断开事件 telnetConn.on('end', () => { console.log(`[${connNum}] 连接已断开`); }); // 发起连接并捕获异常 try { await telnetConn.connect(connOpts); } catch (err) { console.error(`[${connNum}] 连接失败:`, err.message); } } // 批量创建10个连接,间隔750ms async function initConnections() { for (let i = 0; i < 10; i++) { console.log(`[${i}] 准备创建第${i+1}个连接`); // 非阻塞创建连接,避免单个连接失败阻塞后续 createTelnetConn(i); // 等待750ms再创建下一个 await new Promise(resolve => setTimeout(resolve, 750)); } } // 启动脚本 initConnections();
额外排查建议
- 先手动用Telnet命令测试单个连接是否正常:
telnet srvAP 23,输入账号密码确认能登录; - 检查目标服务器的Telnet服务配置:
- 确认服务是否启动:
systemctl status telnet.socket(Linux); - 检查是否限制并发连接:查看
/etc/security/limits.conf中的连接数相关配置; - 确认防火墙是否允许客户端IP访问23端口;
- 确认服务是否启动:
- 如果还是频繁失败,可以给连接添加重试逻辑,比如失败后间隔3秒重试1次。
内容的提问来源于stack exchange,提问作者blank98800
相关产品推荐
相关产品推荐

