JSch: How to keep the session alive and up

匿名 (未验证) 提交于 2019-12-03 01:07:01

问题:

I'm writing Java GUI program for static route management using SSH. My code is as follows:

import com.jcraft.jsch.*; import java.io.*;  public class Konsep {     String status;     static String username;     static String hostname;     String inputcommand;     String output;     static Session session;      JSch jsch = new JSch();      public String status(String stringstatus) {         stringstatus = status;         return stringstatus;     }      public String InputCommand(String inputcommandstatus) {         inputcommandstatus = inputcommand;         return inputcommandstatus;     }      public void connect(String usernamelokal, String hostnamelokal,             String password, int port) {         //        JSch jsch=new JSch();         try {             Session sessionlokal = jsch.getSession(usernamelokal,                     hostnamelokal, port);             sessionlokal.setPassword(password);             UserInfo ui = new UserInfoku.Infoku();             sessionlokal.setUserInfo(ui);             sessionlokal.setTimeout(0);             sessionlokal.connect();             status = "tersambung \n";             username = usernamelokal;             hostname = hostnamelokal;             session = sessionlokal;             System.out.println(username + " " + hostname);         } catch (Exception e) {             System.out.println(e);             status = "Exception = \n " + e + "\n";          }     }      public void disconnect() {         //        JSch jsch=new JSch();         try {             Session sessionlokal = jsch.getSession(username, hostname);             //            System.out.println(username +" "+ hostname);             sessionlokal.disconnect();             status = "wes pedhoott \n";         } catch (Exception e) {             System.out.println(e);             status = "Exception = \n " + e + "\n";         }      }      public void addRoute() {         //        JSch jsch=new JSch();         System.out.println(username + " " + hostname);         try {             Session sessionlokal = session; // =jsch.getSession(username, hostname);             Channel channel = sessionlokal.openChannel("exec");             ((ChannelExec) channel).setCommand(inputcommand);             channel.setInputStream(null);             channel.connect();             ((ChannelExec) channel).setErrStream(System.err);             InputStream in = channel.getInputStream();             channel.connect();              byte[] tmp = new byte[1024];             while (true) {                 while (in.available() > 0) {                     int i = in.read(tmp, 0, 1024);                     if (i 

The problem is when I call the connect method and then calling the addroute, the program returns

root 192.168.50.2 root 192.168.50.2 com.jcraft.jsch.JSchException: session is down 

I've been trying to get session status with either

Session sessionlokal=session; //returns com.jcraft.jsch.JSchException: ChannelExec 

or

Session sessionlokal=jsch.getSession(username, hostname); //returns session is down 

I've also tried to use keepalive, but its not working either.

My intention is to create a session to host (log in), while leaving the session up, execute a command or commands and maybe executing other commands later, and then closing the session when its not needed (log out). I've been searching on this forum and I found this question but the code is create a method to define a command to execute first, and then creating the session, call the command's method and close the session.

Any ideas about how to do as I mentioned above ?

回答1:

After trying Session.sendKeepAliveMsg() without success, I came to the following solution which seems to be rather stable:

private Session getSession() throws Exception {     try {         if (!session.isConnected()) {             logger.info("Session nicht konnektiert. Versuche (erneut) zu konnektieren.");             session.connect();         }     } catch (Throwable t) {         logger.info("Session kaputt. Baue neue.");         session = jsch.getSession(user, host, port);         session.setConfig(config);         session.connect();     }     return session; } 

Update: Some days later it failed.

I tried to test it by killing the open session on the server. All prior versions I tested this way showed the exact same behaviour, regardless wheater the problem poped up after waiting some days or killing the server process, so I thought this test - and its outcome for the above solution - to be meaningful. Unfortunately it isn't.

I'm going to try some other ways to fix it and keep you up to date.

Update 2: Final solution, guarateed unelegant and working:

private Session getSession() throws Exception {     try {         ChannelExec testChannel = (ChannelExec) session.openChannel("exec");         testChannel.setCommand("true");         testChannel.connect();         if(logger.isDebugEnabled()) {             logger.debug("Session erfolgreich getestet, verwende sie erneut");         }         testChannel.exit();     } catch (Throwable t) {         logger.info("Session kaputt. Baue neue.");         session = jsch.getSession(user, host, port);         session.setConfig(config);         session.connect();     }     return session; } 

This version runs several weeks in a productive environment. Once a day I have the info message logged.

The costs of opening a channel and performing some do-nothing-command are somewhat annoying, but I found no other way to be definitly sure about the state of the session.



回答2:

You can try by invoking the following method before invoking Session#connect().

Session#setServerAliveInterval(int milliseconds)

Although I found one more function Session#sendKeepAliveMsg() which can be tried.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!