Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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 
";
            username = usernamelokal;
            hostname = hostnamelokal;
            session = sessionlokal;
            System.out.println(username + " " + hostname);
        } catch (Exception e) {
            System.out.println(e);
            status = "Exception = 
 " + e + "
";

        }
    }

    public void disconnect() {
        //        JSch jsch=new JSch();
        try {
            Session sessionlokal = jsch.getSession(username, hostname);
            //            System.out.println(username +" "+ hostname);
            sessionlokal.disconnect();
            status = "wes pedhoott 
";
        } catch (Exception e) {
            System.out.println(e);
            status = "Exception = 
 " + e + "
";
        }

    }

    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 < 0)
                        break;
                    System.out.print(new String(tmp, 0, i));
                }
                if (channel.isClosed()) {
                    System.out.println("exit-status: "
                            + channel.getExitStatus());
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (Exception ee) {
                }
            }

            channel.disconnect();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}      

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 ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
284 views
Welcome To Ask or Share your Answers For Others

1 Answer

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 successfully tested, use it again.");
            session.connect();
        }
    } catch (Throwable t) {
        logger.info("Session terminated. Create a new one.");
        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 behavior, regardless whether the problem popped 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, guaranteed inelegant 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 successfully tested, use it again.");
        }
        testChannel.exit();
    } catch (Throwable t) {
        logger.info("Session terminated. Create a new one.");
        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 definitely sure about the state of the session.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...