我的应用程序通过SSH连接到服务器(使用JSch),但是如果我发送命令而不等待结果返回它并且它错过了回复,因为下一个命令在没有等待的情况下发送,应用程序无法跟上。 / p>
我尝试了一些方法,例如使用Object同步Thread并使用wait()和notify(),但UI线程保持冻结状态。而thread.join()虽然有效但导致它在命令之间冻结时运行速度非常慢。
长话短说,我需要等待服务器的回复,处理并绘制它,然后发送下一个命令。
非常感谢任何帮助,因为这是我的计算项目。 :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
我已经读过我可以在这里使用AsyncTask而不是线程...不确定我是否可以在服务中执行此操作,但是......:P
答案 0 :(得分:0)
请参阅#sending-commands-to-server-via-jsch-shell-channel
...如果您不确定要阅读多少行并因此想要 使用“while”,确保你在内部做一些事情,以防止1) 忙碌的等待2)结束条件。例如:
while(!end)
{
consoleOutput.mark(32);
if (consoleOutput.read()==0x03) end = true;//End of Text
else
{
consoleOutput.reset();
consoleOutput.readLine();
end = false;
}
}
要从其他主题处理您的输入内容,您可以使用#non-blocking-buffer
此外,作为设计建议,您可以使用UserInfo界面来传递您的凭据,而不是直接从您的UI对象。
与您的类似项目(基于网络,而不是Android):https://github.com/kohsuke/ajaxterm4j