我正在尝试构建基于Jframe的SSH客户端。我已连接客户端,输出流通过管道连接到JTextArea。
问题在于用户输入,取自JTextArea下面的JTextField,当用户按下enter并发送到服务器时读取。
public class InputArea extends InputStream {
byte[] contents;
int pointer = 0;
public InputArea(JTextField inputarea) {
TextPrompt consoleTp = new TextPrompt(">> ", inputarea);
consoleTp.setShow(TextPrompt.Show.FOCUS_LOST);
inputarea.setPreferredSize(new Dimension(560, 40));
inputarea.setVisible(true);
// Fire listener for input area when enter key is pressed .
inputarea.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyChar() == '\n') {
contents = inputarea.getText().getBytes();
pointer = 0;
inputarea.setText("");
}
super.keyReleased(e);
}
});
}
@Override
public int read() throws IOException {
if (pointer >= contents.length) return -1;
return this.contents[pointer++];
}
}
此类扩展InputStream,并按下回车键监听用户。从那里它读取JTextField的内容,并且(希望)将其设置为'contents',当非空白时由InputStream读取。
从那里,在控制台窗口的主JFrame类中;
//
// Configure input area
//
JTextField inputTextField = new JTextField();
in = new InputArea(inputTextField);
add(inputTextField);
然后在连接SSH服务器的方法中;
Session session = jsch.getSession(user,host,port);
// Disable key checking
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setPassword(String.valueOf(password));
System.out.println("Attempting to connect to " + host + " on port " + port + " ....");
session.connect(3000);
Channel channel = session.openChannel("shell");
channel.setInputStream(in);
channel.setOutputStream(out);
channel.connect(3000);
System.out.println("Connected.");
服务器的输出流功能正常(参见下面的屏幕截图),当输入命令并按下返回键时,TextField将重置其内容。但是,此命令不会发送到服务器(通过运行mkdir Testing ect进行测试)。
任何建议都将不胜感激。如果您需要完整的代码示例,可以在https://github.com/ElliotAlexander/SSH-Connect-GUI找到。
答案 0 :(得分:0)
您发送到远程服务器的命令不会被执行,因为它们不会被换行符终止。
您的代码只发送输入字段的文本,但新行字符会被您的代码“吞噬”。要解决此问题,只需在字节缓冲区中附加换行符即可。另外,我认为扩展InputStream类的方式会导致一些问题,因为只有Jsch通道才会调用read方法。
我建议使用一对管道流对象。您需要在ConsoleWindow中初始化它们并将它们传递给InputArea和channel:
private PipedInputStream pin;
private PipedOutputStream pout;
public ConsoleWindow(...) {
pin = new PipedInputStream();
pout = new PipedOutputStream(pin);
// InputArea no longer needs to extend InputStream
in = new InputArea(inputTextField, pout);
...
}
private void SSHConnect() {
...
channel.setInputStream(pin);
...
}
最后,将命令写入输出流:
public InputArea(final JTextField inputarea, final PipedOutputStream pout) {
...
public void keyReleased(KeyEvent e) {
if (e.getKeyChar() == '\n') {
byte[] tmp = inputarea.getText().getBytes();
pout.write(tmp, 0, tmp.length);
pout.write('\n');
...
}
...
}
}