I have my application connecting to a server over SSH (Using JSch) but the app cant keep up if I send commands without waiting for the result to come back and it misses the reply as the next command gets sent without waiting.
I have tried a few methods e.g. using an Object to synchronize the Thread and using wait() and notify() but the UI thread stays frozen doing this. And thread.join() which worked but resulted in it running very slowly as it froze between commands.
Long story short, I need to wait for a reply from the server, process it and plot it, then send the next command.
Any help is greatly appreciated as this is for my Computing project. :D
//A snippet of my service procedure that handles the SSH connections
public String sendCommand(final String command) {
Finished = false;
final Thread sshServiceThread = new Thread(new Runnable() {
String sshPassword = null;
private volatile boolean running = true;
@Override
public void run () {
while (running) {
try {
session = jSch.getSession(username, host, port);
checkPassword();
session.setPassword(sshPassword);
session.setConfig("StrictHostKeyChecking", "no");
//TODO - REMOVE THIS
Log.w("DEBUG", "Host: " + host + " Username: " + username + " Password: " + password);
Log.w("Security", "REMOVE THIS BEFORE RELEASE");
session.connect();
channel = session.openChannel("shell");
DataOutputStream dataOut = new DataOutputStream(channel.getOutputStream());
InputStream in = channel.getInputStream();
channel.connect();
//Send command
Log.w("Command", "Command: " + command);
dataOut.writeBytes(command + " && echo TheCommandWasFinished" + "\r\n");
dataOut.flush();
byte[] tmp = new byte[1024];
String replyLine = "";
try {
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0)
break;
String lastLine = replyLine;
replyLine = (new String(tmp, 0, i));
if (!replyLine.contains("&& echo TheCommandWasFinished")) {
if (replyLine.contains("TheCommandWasFinished")) {
String result = lastLine;
Log.w("Result", result);
reply = result;
synchronized (syncObject) {
notify();
}
return;
}
}
}
}
} catch (Exception exception) {
Log.w("Exception", exception);
}
} catch (JSchException jschX) {
Log.w("Exception", jschX);
if (jschX.toString().contains("timeout")) {
Log.w("Error", "IP Address is incorrect");
Toast.makeText(getApplicationContext(), "Cannot connect to host, Check IP and connection.", Toast.LENGTH_LONG).show();
}
if (jschX.toString().contains("Auth fail")) {
Log.w("Error", "Username/Password Incorrect");
Toast.makeText(getApplicationContext(), "Username/Password Incorrect", Toast.LENGTH_LONG).show();
}
if (jschX.toString().contains("ECONNRESET")) {
Toast.makeText(getApplicationContext(), "Connection failure", Toast.LENGTH_LONG).show();
}
} catch (IOException Exception) {
Log.w("Exception", Exception);
}
}
}
void checkPassword() {
Log.w("Password set", "Password: " + sshService.password);
sshPassword = sshService.password;
}
});
sshServiceThread.start();
try {
synchronized(syncObject) {
syncObject.wait(3000);
}
}
catch (Exception Exception) {
Log.w("Exception", Exception);
}
Finished = true;
return reply;
}
// Last few lines of my Logcat
02-12 00:11:10.281 32701-32701/com.lonedev.slypanel W/Values﹕ Host: 192.168.0.14 Username: adam
02-12 00:11:10.282 32701-32701/com.lonedev.slypanel W/Save﹕ Saved 192.168.0.14 adam
02-12 00:11:10.354 32701-32701/com.lonedev.slypanel W/Host:﹕ 192.168.0.14
02-12 00:11:10.355 32701-32701/com.lonedev.slypanel W/Host:﹕ 192.168.0.14
02-12 00:11:13.398 32701-684/com.lonedev.slypanel W/Password set﹕ Password: **********
02-12 00:11:13.399 32701-684/com.lonedev.slypanel W/DEBUG﹕ Host: 192.168.0.14 Username: adam Password: **********
02-12 00:11:13.399 32701-684/com.lonedev.slypanel W/Security﹕ REMOVE THIS BEFORE RELEASE
02-12 00:11:13.794 32701-684/com.lonedev.slypanel W/Command﹕ Command: top -b -n2 | grep "Cpu(s)" | awk '{print $2 + $4}' | tail -1
// This should return a value for cpu usage e.g. 37.5
// UI Freezes here
I have read that I could use an AsyncTask here instead of a thread... Not sure if I can do that inside of a Service though... :P