apache / mina-sshd

Apache MINA sshd is a comprehensive Java library for client- and server-side SSH.
https://mina.apache.org/sshd-project/
Apache License 2.0
847 stars 353 forks source link

a problem when ChannelExec warned:handleEof-someInfo-already signalled #490

Closed merlynee closed 2 months ago

merlynee commented 2 months ago

Version

2.12.1

Bug description

I use sshd-core to execute the hostname . But sometimes I got twice of the result. When this result appears , it usually report: handleEof(ChannelExec[id=0, recipient=1]-ClientSessionImpl[root@/10.253.146.1:22]) already signalled. I tested for several times and it happens once outof twenty or thirty times. My code is like following: public String testGetHostName(@RequestParam String ip, @RequestParam int port, @RequestParam String username, @RequestParam String pwd) { for (int i = 0; i < 50; i++) { SSHUitls.execCommand(ip, username, pwd, port, "hostname", i); } return SSHUitls.execCommand(ip, username, pwd, port, "hostname",51); } @Slf4j public class SSHUitls { public synchronized static String execCommand(@NonNull String ip, @NonNull String username, @NonNull String pass, int port, String cmd, int count) { ClientSession session = null; ChannelExec shellChannelExec = null; ByteArrayOutputStream output = new ByteArrayOutputStream(); ByteArrayOutputStream outputErr = new ByteArrayOutputStream(); SshClient client = SshClient.setUpDefaultClient(); try { log.info("destin:{} cmd:{}", ip, cmd); client.setServerKeyVerifier(AcceptAllServerKeyVerifier.INSTANCE); client.start(); ConnectFuture cf = client.connect(username, ip, port); session = cf.verify().getSession(); session.addPasswordIdentity(pass); session.auth().verify(TimeUnit.SECONDS.toMillis(50)); shellChannelExec = session.createExecChannel(cmd); shellChannelExec.setOut(output); shellChannelExec.setErr(outputErr); log.info("createExecChannel time:" + LocalDateTime.now()); shellChannelExec.open().verify(15L, TimeUnit.SECONDS); log.info("exec during:" + LocalDateTime.now()); shellChannelExec.open(); shellChannelExec.waitFor(EnumSet.of(ClientChannelEvent.CLOSED), 0); shellChannelExec.setOut(null); log.info("destin:{} cmd:{} error:{} standred{}", ip, cmd, outputErr, output); String outputStr = output.toString(); String[] splitStr = outputStr.split("\n"); try{ Thread.sleep(300); }catch (InterruptedException e){ e.printStackTrace(); } if (splitStr.length > 1) { log.error("duplicate happens:" + count); } return output.toString(); } catch (Exception e) { log.error("exec error:{}", e.getMessage()); } finally { if (shellChannelExec != null) { try { shellChannelExec.close(); } catch (Exception e) { log.error("shellChannelExec disconnect error:", e); } } try { output.close(); } catch (Exception e) { log.error("shellStream close error:", e); } try { outputErr.close(); } catch (Exception e) { log.error("shellErrStream close error:", e); } } return ""; } } With the logs following: 20240425143923 So much apreciate it if someone could spare your time to help!

Actual behavior

Got twice of the result,when I apply for hostname frequently.

Expected behavior

To get the result onece.Or I can get the Exception or Callback

Relevant log output

No response

Other information

No response

tomaswolf commented 2 months ago

I'm not here to debug your code. I do notice, however, that you call shellChannelExec.open() twice.

merlynee commented 2 months ago

I'm not here to debug your code. I do notice, however, that you call shellChannelExec.open() twice. Thanks somuch fellow.!!!