使用JSch通过SSH会话执行Telnet命令无法获取返回结果怎么办
问题原因与修复方案
核心问题
- 命令发送无等待:你一次性连续发送了telnet连接命令、业务指令、exit退出指令,业务指令还没来得及执行返回,telnet就已经退出了,自然捕获不到返回结果。
- 读取逻辑错误:你的循环终止条件是匹配到
exit字符串,但你发送的exit是输入给telnet进程的指令,远程返回的输出流里不会出现单独的exit行,会导致要么循环提前终止要么触发空指针异常。 - 无输出缓冲刷新处理:交互型shell通道的输出存在缓冲,未做延迟/主动读取逻辑会导致部分输出没来得及被读取就关闭了通道。
修复后的代码
直接修改Telnet类的runCommand方法即可:
public String runCommand(Session session, String command) throws Exception { Channel channel = session.openChannel("shell"); channel.connect(3000); DataOutputStream outputStream = new DataOutputStream(channel.getOutputStream()); BufferedReader reader = new BufferedReader(new InputStreamReader(channel.getInputStream())); StringBuilder result = new StringBuilder(); String line; // 第一步:发送telnet连接命令,等待连接完成 outputStream.writeBytes("telnet localhost 5000\r\n"); outputStream.flush(); // 等待telnet连接成功,匹配到服务提示符后再发业务指令,可根据实际提示符调整匹配规则 Thread.sleep(1000); while (reader.ready()) { line = reader.readLine(); result.append(line).append("\n"); if (line.contains(">")) { break; } } // 第二步:发送业务命令,读取返回结果 outputStream.writeBytes(command + "\r\n"); outputStream.flush(); Thread.sleep(1000); while (reader.ready()) { line = reader.readLine(); result.append(line).append("\n"); } // 第三步:发送exit退出telnet,收尾读取剩余输出 outputStream.writeBytes("exit\r\n"); outputStream.flush(); Thread.sleep(500); while (reader.ready()) { line = reader.readLine(); result.append(line).append("\n"); } result.append("Connection closed by foreign host"); outputStream.close(); reader.close(); channel.disconnect(); session.disconnect(); return result.toString(); }
优化建议
- 生产环境不要用
Thread.sleep做固定等待,可以改成轮询reader.ready()状态,设置最大超时时间避免死等。 - 如果你连接的telnet服务有固定的输出结束标识,可以用该标识代替固定等待时间,读取精度更高。
- 原有代码中
session.setConfig("StrictHostKeyChecking", "no")是跳过主机密钥校验,仅适合测试环境使用,生产环境请配置合法的主机密钥。 - 可以把telnet的端口、提示符这些参数抽成配置项,适配不同的telnet服务。
内容的提问来源于stack exchange,提问作者Alexey Zhukov
相关产品推荐
相关产品推荐

