首页 > 解决方案 > 通过 SSH 隧道的 Java Swing 应用程序 MySQL 连接失败,并显示“本地端口 127.0.0.1:...无法绑定...地址已在使用中:JVM_Bind”

问题描述

我希望 Java Swing 桌面应用程序连接到在 Linux 服务器中运行的 MySQL 数据库。

我用 MySQL Workbench 连接到这个数据库,使用 SSH 连接,这里没有问题,但是从代码中......到目前为止是不可能的。

我尝试了以下方法:

private static void doSshTunnel( String strSshUser, String strSshPassword, String strSshHost, 
        int nSshPort, String strRemoteHost, int nLocalPort, int nRemotePort ) throws JSchException {
    
    final JSch jsch = new JSch();
    Session session = jsch.getSession( strSshUser, strSshHost, 22 );
    session.setPassword( strSshPassword );
     
    final Properties config = new Properties();
    config.put( "StrictHostKeyChecking", "no" );
    session.setConfig( config );
     
    session.connect();
    session.setPortForwardingL(nLocalPort, strRemoteHost, nRemotePort);
}

public static final Connection conexion() throws JSchException, SQLException {
    
    Connection con = null;
    
    try {
        
        String strSshUser = "xxxx";                  // SSH loging username
        String strSshPassword = "xxx";                   // SSH login password
        String strSshHost = "12.345.678.901";          // hostname or ip or SSH server
        int nSshPort = 22;                                    // remote SSH host port number
        String strRemoteHost = "127.0.0.1";  // hostname or ip of your database server
        int nLocalPort = 1234;                                // local port number use to bind SSH tunnel
        int nRemotePort = 3306;                               // remote port number of your database 
        String strDbUser = "dbuser";                    // database loging username
        String strDbPassword = "dbpw";                    // database login password
           
        doSshTunnel(strSshUser, strSshPassword, strSshHost, nSshPort, strRemoteHost, nLocalPort, nRemotePort);
           
        Class.forName("com.mysql.cj.jdbc.Driver");
        con = DriverManager.getConnection("jdbc:mysql://localhost:"+nLocalPort+"/dbname", strDbUser, strDbPassword);

    } catch (ClassNotFoundException e) {            
        e.printStackTrace();
    } catch (JSchException e) {
        e.printStackTrace();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    
    
    return con;
}

但我得到了错误:

com.jcraft.jsch.JSchException: PortForwardingL: local port 127.0.0.1:1234 cannot be bound.

...

Caused by: java.net.BindException: Address already in use: JVM_Bind

我在其他一些帖子中看到过这个问题...尝试更改端口1234不起作用...我尝试了许多端口,但我总是得到相同的结果...

标签: javamysqlsshjschssh-tunnel

解决方案


一般来说,不要绑定特定的端口。无论您选择哪个,您最终都会与其他一些软件发生冲突。使系统自动分配任何空闲的本地端口:

int nLocalPort = session.setPortForwardingL(0, strRemoteHost, nRemotePort);

尽管在您的情况下,事实证明您多次运行代码片段,所以问题是您与自己发生冲突。

您必须关闭 SSH 会话才能释放转发的端口,然后才能再次重用它。

或者在您的应用程序/服务的整个生命周期中只打开一个会话。


推荐阅读