将JSch Channel InputStream连接到JTextField框,命令未被发送

时间:2016-08-02 16:32:18

标签: java jframe inputstream outputstream jsch

我正在尝试构建基于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找到。

The connected terminal output

1 个答案:

答案 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');
            ...
        }
        ...
    }
}