java SWT 使用 Jcraft JSch 连接到远程服务器
java SWT to connect to remote server using Jcraft JSch
我正在开发一个工具,使用 jcraft.JSch(ssh 到 Unix 服务器)和 return 输出和显示来连接到远程服务器它的输出(类似于 putty,但我不喜欢 Plink 或任何第三方的东西)。当通道输入输出为 System.in
和 System.out
并且程序只是一个控制台 java 应用程序时,代码工作正常。但是当我尝试使用 SWT 控件时,出现了 How to Map System.out and System.in to SWT controls
中解释的问题
所以,我相信它与 INFO 和 ERR 标记无关(我稍后会处理),无论如何我改变了方法。现在我通过 SWT 文本输入输入命令。它适用于单线输出。但不适用于多行。
触发连接到shell并发送命令的代码如下。
public void widgetSelected(SelectionEvent e) {
String command=CmdText.getText();
System.out.println("runButton.widgetSelected:Command Obtained by buton is:"+command);
if ( command.equals("") )
{
MessageDialog.openInformation(dialogShell,"Information","Please Eneter a Command!");
return;
}
else if (command.contains("@"))
{
channel=CommandHandler.openshell();
LogText.append("Connected to - :"+command+"\n>");
}
else
{
LogText.append(command+"\n");
String outputstring="";
try
{
BufferedReader dataIn = new BufferedReader(new InputStreamReader(channel.getInputStream()));
DataOutputStream dataOut = new DataOutputStream(channel.getOutputStream());
dataOut.writeBytes(command+"\n");
dataOut.flush();
String line="";
outputstring=""+line;
while ( line != null) {
try
{
line = dataIn.readLine();
line = dataIn.readLine();
LogText.append("<CommandResult>:"+line+"\n");
return;
}
catch (IOException e1) { B24IDEConsole.WriteLog("RemoteCall.connect_execute", e1.getMessage()); }
outputstring=outputstring+line;
}
}
catch(Exception e1){ B24IDEConsole.WriteLog("RemoteCall.connect_execute", e1.getMessage()); }
LogText.append("<EndOfCommand>:"+outputstring+"\n");
}
}
当我在 while 循环中删除 return 时,对话框和 eclipse(触发对话框)变得不-反应灵敏,我必须杀了他们两个。
感谢您的帮助,感谢您的宝贵时间。
上面的代码中我遗漏了两件事。
- getOutputStream 和 getInputStream 在 channel.connect 之后被调用,而 Jsch 文档说它不应该是 ref: http://epaul.github.io/jsch-documentation/simple.javadoc/com/jcraft/jsch/Channel.html
- dataIn.available 是一个更好的测试,如果有更多的数据可用 来自服务器 或没有。感谢 Sending commands to server via JSch shell channel.
更新后的代码是
InputStream dataIn = CommandHandler.getdatain();
OutputStream dataOut = CommandHandler.getdataout();
//dataOut.write(command.getBytes()+"\n");
byte[] inputbytes = command.getBytes();
dataOut.write(inputbytes,0,inputbytes.length);
dataOut.flush();
while (true) {
boolean readoutput=false;
while (dataIn.available() > 0) {
readoutput=true;
byte[] buffer=new byte[1024];
int i = dataIn.read(buffer, 0, 1024);
if (i < 0) {
System.out.print("No more data available!");//It is printing the response to console
break;
}
LogText.append(new String(buffer, 0, i));
//LogText.append(":"+new String(buffer, 0, i)+"\n>");
System.out.print(new String(buffer, 0, i));//It is printing the response to console
}
System.out.println(dataIn.available()+"done");
if ( readoutput )
{
if ( dataIn.available() == 0 )
{
System.out.print("Read all the data and no nore is available, hence exiting!\n");//It is printing the response to console
break;
}
}
if ( channel.isClosed() ) {
System.out.println("exit-status: " + channel.getExitStatus());
break;
}
try{Thread.sleep(1000);}catch(Exception ee){}
}
break 仍然是个问题,但看起来现在可以修复了。
我正在开发一个工具,使用 jcraft.JSch(ssh 到 Unix 服务器)和 return 输出和显示来连接到远程服务器它的输出(类似于 putty,但我不喜欢 Plink 或任何第三方的东西)。当通道输入输出为 System.in
和 System.out
并且程序只是一个控制台 java 应用程序时,代码工作正常。但是当我尝试使用 SWT 控件时,出现了 How to Map System.out and System.in to SWT controls
所以,我相信它与 INFO 和 ERR 标记无关(我稍后会处理),无论如何我改变了方法。现在我通过 SWT 文本输入输入命令。它适用于单线输出。但不适用于多行。
触发连接到shell并发送命令的代码如下。
public void widgetSelected(SelectionEvent e) {
String command=CmdText.getText();
System.out.println("runButton.widgetSelected:Command Obtained by buton is:"+command);
if ( command.equals("") )
{
MessageDialog.openInformation(dialogShell,"Information","Please Eneter a Command!");
return;
}
else if (command.contains("@"))
{
channel=CommandHandler.openshell();
LogText.append("Connected to - :"+command+"\n>");
}
else
{
LogText.append(command+"\n");
String outputstring="";
try
{
BufferedReader dataIn = new BufferedReader(new InputStreamReader(channel.getInputStream()));
DataOutputStream dataOut = new DataOutputStream(channel.getOutputStream());
dataOut.writeBytes(command+"\n");
dataOut.flush();
String line="";
outputstring=""+line;
while ( line != null) {
try
{
line = dataIn.readLine();
line = dataIn.readLine();
LogText.append("<CommandResult>:"+line+"\n");
return;
}
catch (IOException e1) { B24IDEConsole.WriteLog("RemoteCall.connect_execute", e1.getMessage()); }
outputstring=outputstring+line;
}
}
catch(Exception e1){ B24IDEConsole.WriteLog("RemoteCall.connect_execute", e1.getMessage()); }
LogText.append("<EndOfCommand>:"+outputstring+"\n");
}
}
当我在 while 循环中删除 return 时,对话框和 eclipse(触发对话框)变得不-反应灵敏,我必须杀了他们两个。
感谢您的帮助,感谢您的宝贵时间。
上面的代码中我遗漏了两件事。
- getOutputStream 和 getInputStream 在 channel.connect 之后被调用,而 Jsch 文档说它不应该是 ref: http://epaul.github.io/jsch-documentation/simple.javadoc/com/jcraft/jsch/Channel.html
- dataIn.available 是一个更好的测试,如果有更多的数据可用 来自服务器 或没有。感谢 Sending commands to server via JSch shell channel.
更新后的代码是
InputStream dataIn = CommandHandler.getdatain();
OutputStream dataOut = CommandHandler.getdataout();
//dataOut.write(command.getBytes()+"\n");
byte[] inputbytes = command.getBytes();
dataOut.write(inputbytes,0,inputbytes.length);
dataOut.flush();
while (true) {
boolean readoutput=false;
while (dataIn.available() > 0) {
readoutput=true;
byte[] buffer=new byte[1024];
int i = dataIn.read(buffer, 0, 1024);
if (i < 0) {
System.out.print("No more data available!");//It is printing the response to console
break;
}
LogText.append(new String(buffer, 0, i));
//LogText.append(":"+new String(buffer, 0, i)+"\n>");
System.out.print(new String(buffer, 0, i));//It is printing the response to console
}
System.out.println(dataIn.available()+"done");
if ( readoutput )
{
if ( dataIn.available() == 0 )
{
System.out.print("Read all the data and no nore is available, hence exiting!\n");//It is printing the response to console
break;
}
}
if ( channel.isClosed() ) {
System.out.println("exit-status: " + channel.getExitStatus());
break;
}
try{Thread.sleep(1000);}catch(Exception ee){}
}
break 仍然是个问题,但看起来现在可以修复了。