0

I am writing an app to connect over SSH to a server. My intention is to give the user of the app an internet connection as long as they are connected to the server (The SSH Script runs as Android Service). The Problem is, when I start a session and create a channel everything works fine. But after about 20-30 minutes (sometimes up to several hours) the channel and the session closes.

Connect function:

 public String connecting(
        String username,
        final String password,
        String hostname,
        int port) {

    try {
        Log.d("MainActivity", "Start JSch session and connect");
        jsch = new JSch();
        session = jsch.getSession(username, hostname, port);

        session.setPassword(password);

        // Avoid asking for key confirmation
        Properties prop = new Properties();
        prop.put("StrictHostKeyChecking", "no");
        session.setConfig(prop);
        session.connect();
        session.setServerAliveInterval(15);
        session.setServerAliveCountMax(100);


        Channel channel = session.openChannel("shell");
        channel.setInputStream(System.in);
        channel.setOutputStream(System.out);
        channel.connect();

        InputStream in = channel.getInputStream();
        serviceStatus = true;
        streamtext = "";
        byte[] tmp = new byte[1024];
        while (true) {
            while (in.available() > 0) {
                int i = in.read(tmp, 0, 1024);
                if (i < 0) break;
                streamtext = new String(tmp, 0, i);

                }
            }
            if (channel.isClosed()) {
                if (in.available() > 0) continue;
                Log.d(TAG, "exit-status: " + channel.getExitStatus());
                break;
            }
            try {
                Thread.sleep(1000);
            } catch (Exception ee) {
                ee.printStackTrace();
            }
        }

        return streamtext;
    } catch (Exception except){
        except.printStackTrace();
        passErrorToActivity("Error: Connection error");
        return "Error: Connection error";
    }
}

Start function:

public void start(){
        try {
            new AsyncTask<Integer, Void, Void>() {
                @Override
                protected Void doInBackground(Integer... params) {
                    try {
                    passMessageToActivity(connecting(user, password, host, port));
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                    return null;
                }
            }.execute(1);
        } catch (Exception exc) {
            exc.printStackTrace();
        }

"passMessageToActivity" Just creats an intent and sends the "streamtext" to the MainActivity

I've already tryed it with Session#setServerAliveInterval(int milliseconds) but it didn't work. Is there any posibility to keep the session and channel alive? I've seen the solution of this user but this doesn't work for me because it's important that the connection between server and service is always up.

1 Answers1

0
  • If setting keepalives only does not help, you need to keep the session busy with more high-level actions. Like sending a dummy command, like pwd. Though you may need to explain, why you have "shell" session open, that look suspicious.
  • Anyway, there's no way you can guarantee that a connection stays alive. You would have to deal with losing connection occasionally anyway.
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • Thank you! I'll give it a try. The shell channel ist just there to receive the data from the server once. I can also use an "Exec" or any other channel. Maybe you know the app "Termius" on android where you can connect to a server over ssh and then the session and the command promt stays in the background and the session is alive without sending any commands. – ItsRedstone Apr 24 '18 at 08:43