【问题标题】:JSch/SSHJ - Connecting to SSH server on button clickJSch/SSHJ - 单击按钮连接到 SSH 服务器
【发布时间】:2011-07-25 16:21:19
【问题描述】:

我正在尝试通过单击按钮连接到 SSH Unix 服务器(使用 actionPerformed() 方法编写的代码)。我正在使用 JSch 连接到 SSH 服务器。代码写在 SwingWorker 类中,因为它是一个网络操作。

private void testConnectionButtonActionPerformed(java.awt.event.ActionEvent evt) {                                                     

        SwingWorker<Boolean, Void> sw = new SwingWorker<Boolean, Void>(){

            @Override
            protected Boolean doInBackground() throws Exception {
                JSch jsch = new JSch();

                String host = "ServerHost";
                String username = "username";
                String password = "password";

                Session session = jsch.getSession(username, host);
                session.setPassword(password);

                session.setTimeout(20000);
                System.out.println("Connecting to server...");
                session.connect();

                return true;
            }

            @Override
            public void done(){
                try {
                    System.out.println(get().toString());
                } catch (Exception ex) {
                    System.out.err(ex);
                } 
            }
        };

        sw.execute();

    }  

但是在使用正确的主机、用户名和密码详细信息运行后,我一直收到以下错误:

com.jcraft.jsch.JSchException: timeout: socket is not established
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
    at java.util.concurrent.FutureTask.get(FutureTask.java:83)
    at javax.swing.SwingWorker.get(SwingWorker.java:583)

但是每当我在独立程序中运行相同的代码时,我的意思是改为编写 actionPerformed() 方法,如果我用普通方法编写它并从 main() 方法调用。它会起作用的。当我将相同的代码与 Button Click 的 actionPerformed() 方法集成时,它会给我上述异常。

谁能建议我在这里做错了什么或者应该对代码进行任何修改。

我尝试使用“SSHJ”实现连接到 SSH 服务器,但出现以下错误:

java.net.SocketException: Connection reset
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
    at java.util.concurrent.FutureTask.get(FutureTask.java:83)
    at javax.swing.SwingWorker.get(SwingWorker.java:583)

有人可以帮助我 - 如何前进?

【问题讨论】:

  • 它适用于我(如果我更改服务器名称、密码和设置以接受服务器的公钥,并更正您的system.out.err)。
  • Paulo,你能告诉我你想让我接受服务器公钥的设置是什么,一段代码真的很有帮助。谢谢。
  • JSch.setConfig("StrictHostKeyChecking", "no")。但这不是你的问题,你的程序甚至没有达到这一点(连接被拒绝或不允许)。检查您的防火墙设置。
  • 在您要求我输入代码以接受服务器的公钥后,我做了同样的事情,但它没有连接到服务器,防火墙设置很好,因为当我独立运行它时没有放置actionPerformed() 方法中的代码 - 它可以工作,但是当我将此代码与 actionPerformed() 方法连接时 - 它不会连接。无法找出正确的原因。还有什么建议吗?

标签: button ssh click jsch


【解决方案1】:

我获取了您的代码,将其包装在一些 GUI 代码中(并将其转换为非泛型,以便能够使用与其他 JSch 示例相同的设置对其进行编译)。这个对我有用。试试这个,并报告你得到了什么异常(它有更多的异常记录)。

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;

import com.jcraft.jsch.*;



class SwingWorkerExample {

    JTextField hostField;
    JTextField userNameField;
    JTextField passwordField;
    JPanel panel;


    public SwingWorkerExample() {
        JPanel p = panel = new JPanel(new GridLayout(0,2));
        hostField = new JTextField(20);
        userNameField = new JTextField(20);
        passwordField = new JPasswordField(20);
        JButton testButton = new JButton("connect!");
        testButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent ev) {
                    testConnectionButtonActionPerformed(ev);
                }
            });
        p.add(new JLabel("host:"));
        p.add(hostField);
        p.add(new JLabel("user:"));
        p.add(userNameField);
        p.add(new JLabel("password:"));
        p.add(passwordField);
        p.add(testButton);
    }

    public JPanel getPanel() {
        return panel;
    }

    private void testConnectionButtonActionPerformed(ActionEvent evt) {

        SwingWorker sw = new SwingWorker(){

                protected Object doInBackground() throws Exception {
                    try {
                        JSch jsch = new JSch();

                        String host = hostField.getText();
                        String username = userNameField.getText();
                        String password = passwordField.getText();

                        Session session = jsch.getSession(username, host);
                        session.setPassword(password);
                        session.setConfig("StrictHostKeyChecking", "no");

                        session.setTimeout(20000);
                        System.out.println("Connecting to server...");
                        session.connect();

                        return session;
                    }
                    catch(Exception ex) {
                        ex.printStackTrace();
                        throw ex;
                    }
                }

                public void done(){
                    try {
                        System.out.println(get());
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            };

        sw.execute();

    }


    public static void main(String[] egal) {
        EventQueue.invokeLater(new Runnable(){public void run() {
            SwingWorkerExample ex = new SwingWorkerExample();
            JFrame f = new JFrame("bla");
            f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            f.setContentPane(ex.getPanel());
            f.pack();
            f.setVisible(true);
        }});
    }
}

【讨论】:

  • 这也可以在我的JSch-documentation repository的github上找到(分支swingworker-example,现在)。
  • Paulo,我已经执行了你的代码,它运行良好。我正在使用 Netbeans 7 创建 GUI,有一个类:[org.jdesktop.application.ResourceMap] 使用它从属性文件中获取属性值。我用它来设置按钮文本、标签文本。如果我不在代码中使用此类文件,则 session.connect() 正在工作。我真的不知道这里的关系为什么它无法连接。如果我使用一行 ResourceMap 类,它不会连接。有什么想法吗?
  • 不知道,我没用过这个类。这可能是一个类加载器问题 - 可能某些类在您的类路径中重复,如果使用 ResourceMap,由于某些依赖关系导致加载错误的类?
  • 这个类不在我的类路径中,我尝试使用“javap org.jdesktop.application.ResourceMap”。观察到这种行为很奇怪,所以唯一的办法就是暂时避免这个类?