【问题标题】:access to database remotely-NESTED EXCEPTION远程访问数据库-嵌套异常
【发布时间】:2017-05-14 09:49:26
【问题描述】:

我想在我的java程序中连接到远程数据库ssh,所以我为此编写了一个java代码,我可以从我的代码ssh到数据库服务器但我无法访问数据库,这个是我的输出,其中包含错误: (这个链接是我之前的问题link,和这个问题有关)

hi
identity added
session created.
session connected.....
shell channel connected....
connecting to database ...
db Method...
try-catch
Connecting to database...
DB_URL : jdbc:mysql://localhost:3366/DBNAME
com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception:

** BEGIN NESTED EXCEPTION **

com.mysql.jdbc.CommunicationsException
MESSAGE: Communications link failure due to underlying exception:

** BEGIN NESTED EXCEPTION **

java.io.EOFException
MESSAGE: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.

STACKTRACE:

java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
        at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1997)
        at com.mysql.jdbc.MysqlIO.readPacket(MysqlIO.java:573)
        at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1044)
        at com.mysql.jdbc.Connection.createNewIO(Connection.java:2748)
        at com.mysql.jdbc.Connection.<init>(Connection.java:1553)
        at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
        at java.sql.DriverManager.getConnection(DriverManager.java:664)
        at java.sql.DriverManager.getConnection(DriverManager.java:247)
        at Main.connectToDB(Main.java:78)
        at Main.main(Main.java:49)


** END NESTED EXCEPTION **



Last packet sent to the server was 0 ms ago.

STACKTRACE:

com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception:

** BEGIN NESTED EXCEPTION **

java.io.EOFException
MESSAGE: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.

STACKTRACE:

java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
        at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1997)
        at com.mysql.jdbc.MysqlIO.readPacket(MysqlIO.java:573)
        at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1044)
        at com.mysql.jdbc.Connection.createNewIO(Connection.java:2748)
        at com.mysql.jdbc.Connection.<init>(Connection.java:1553)
        at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
        at java.sql.DriverManager.getConnection(DriverManager.java:664)
        at java.sql.DriverManager.getConnection(DriverManager.java:247)
        at Main.connectToDB(Main.java:78)
        at Main.main(Main.java:49)


** END NESTED EXCEPTION **



Last packet sent to the server was 0 ms ago.
        at com.mysql.jdbc.MysqlIO.readPacket(MysqlIO.java:641)
        at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1044)
        at com.mysql.jdbc.Connection.createNewIO(Connection.java:2748)
        at com.mysql.jdbc.Connection.<init>(Connection.java:1553)
        at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
        at java.sql.DriverManager.getConnection(DriverManager.java:664)
        at java.sql.DriverManager.getConnection(DriverManager.java:247)
        at Main.connectToDB(Main.java:78)
        at Main.main(Main.java:49)


** END NESTED EXCEPTION **



Last packet sent to the server was 1 ms ago.
        at com.mysql.jdbc.Connection.createNewIO(Connection.java:2820)
        at com.mysql.jdbc.Connection.<init>(Connection.java:1553)
        at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
        at java.sql.DriverManager.getConnection(DriverManager.java:664)
        at java.sql.DriverManager.getConnection(DriverManager.java:247)
        at Main.connectToDB(Main.java:78)
        at Main.main(Main.java:49)
Goodbye!
done

我运行这段代码

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

public class Main {

    public static void main(String[] arg) {
        try {
                System.out.println("hi");
            JSch jsch = new JSch();

            String user = "***";
            String host = "**.**.***.***";
            int port = 22;
            String privateKey = "id_rs";

            jsch.addIdentity(privateKey);
            System.out.println("identity added ");

            Session session = jsch.getSession(user, host, port);
            System.out.println("session created.");

            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);

            session.connect();
           session.setPortForwardingL( 3366, host, 3306)  ;

            System.out.println("session connected.....");

            Channel channel = session.openChannel("sftp");
            channel.setInputStream(System.in);
            channel.setOutputStream(System.out);
            channel.connect();
            System.out.println("shell channel connected....");
            System.err.println("connecting to database ...");

           connectToDB();

          System.out.println("done");

        } catch (Exception e) {
            System.err.println(e);
        }
    }


        static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
        static String databaseName ="DBNAME";
       static  int lport = 3366;
        static final String DB_URL = "jdbc:mysql://localhost:"+lport+"/"+databaseName;

        static final String USER = "***";
        static final String PASS = "***";

  public static void connectToDB() {
                System.out.println("db Method...");
                Connection conn = null;
                Statement stmt = null;
                try{
                        System.out.println("try-catch");
                        Class.forName("com.mysql.jdbc.Driver");

                        System.out.println("Connecting to database...");
                        System.err.println("DB_URL : "+DB_URL);
                        System.err.println(USER+":"+PASS+";");
                        conn = DriverManager.getConnection(DB_URL,USER,PASS);

                        System.out.println("hey!");
                        stmt = conn.createStatement();
                        String sql;
                        sql="SELECT * from Customer_Classes ; ";
                        ResultSet rs = stmt.executeQuery(sql);

                       try (BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"))) {
                                while(rs.next()){
                                      String name = rs.getString("ID");
                                      bw.write(name);
                                      bw.newLine();

                                      System.out.println(" name: " + name);
                                }
                                bw.close();
                        } catch (IOException e) {
                                e.printStackTrace();
                        }

                        rs.close();
                        stmt.close();
                        conn.close();
                }catch(SQLException se){
                        se.printStackTrace();
                }catch(Exception e){
                        e.printStackTrace();
                }finally{
                        try{
                                if(stmt!=null)
                                        stmt.close();
                        }catch(SQLException se2){
                            System.err.println("unable to close statement");
                        }
   }
                        try{
                                if(conn!=null)
                                        conn.close();
                        }catch(SQLException se){
                               System.err.println("unable to close connection");
                               se.printStackTrace();
                        }
                }
                System.out.println("Goodbye!");
        }
}

我在远程服务器中定义了一个具有所有权限的用户

GRANT ALL PRIVILEGES ON *.* TO 'USERNAME'@'IP' IDENTIFIED BY 'PASSWORD';

并将我的 Ip 添加到 my.cnf 中的绑定地址(在 DBserver 中)

这个错误意味着什么?我该如何解决?

【问题讨论】:

    标签: java database ssh remote-access


    【解决方案1】:
    1. 当通过端口转发连接时,数据库不会看到你原来的IP地址,而是本地的(localhost)。所以你的资助应该是GRANT ALL PRIVILEGES ON *.* TO 'USERNAME'@'localhost' IDENTIFIED BY 'PASSWORD';
    2. Mysql 的bind-address 参数是用来配置server IP,而不是client IP。您应该将该设置(除非您需要它)保留为默认设置,因为无论如何您都将从 localhost 进行连接。
    3. 如果Channel channel = session.openChannel("sftp");做了它看起来的事情(即将你连接到 SFTP 子系统),sshd 可能不会让你连接到其他地方。你应该使用Channel channel = session.openChannel("shell");
    4. 检查服务器日志。

    【讨论】:

    • 谢谢 :),我用这种语法为我的用户授予了新的权限。并更改 openChannel ,但我很例外。关于第2部分:我不明白,我在数据库服务器中写了绑定地址,你的意思是我应该将它写在代码服务器(要远程访问数据库的服务器)中? ,我检查 /var/log/ 中的安全和消息日志,但找不到任何相关的东西。
    • 你写了“我......将我的 Ip 添加到 my.cnf 中的绑定地址(在 DBserver 中)”。数据库服务器根本看不到您客户端的 IP 地址。所以你不能在数据库服务器端的任何地方配置它,也不能在任何 my.cnf 中配置它。 bind-address 告诉数据库服务器在哪个 IP 上侦听。 session.setPortForwardingL( 3366, host, 3306) 将所有流量转发到地址“主机”上的端口 3306,因此您的数据库服务器应该绑定到该地址。如果你使用session.setPortForwardingL( 3366, "localhost", 3306),那么你的数据库服务器必须监听本地主机(绑定地址:127.0.0.1)
    • 我无法理解 :( ,我将 setportforwadringL 第二个元素更改为 127.0.0.1 ,但不起作用。
    猜你喜欢
    • 2021-01-08
    • 2018-04-02
    • 2018-02-14
    • 2015-05-29
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-20
    相关资源
    最近更新 更多