jdbc无法通过端口转发连接到nat后面的mysql

时间:2014-08-30 07:46:16

标签: java mysql jdbc virtualbox nat

这个问题已经解决了。这是我检查" Connection Refused"错误。

  1. MySQL服务器状态
    • 它在运行吗?
    • 是否禁用了--skip-networking?
    • 是否绑定到地址0.0.0.0?
    • 服务是否被任何防火墙阻止?
    • 是否在日志文件中引发了任何错误/警告/警告?
  2. 客户状态
    • 你能到达服务器ip / url?
    • 你可以用端口telnet服务器吗?
    • 你可以通过同一条网络路由在同一台机器上使用其他mysql客户端软件登录mysql服务吗?
    • 检查防火墙设置
    • 检查mysql连接器/驱动程序 !!
  3. 问题的答案似乎很愚蠢:我使用过时的mysql驱动程序(5.1.9,当前最新版本是5.1.32)。

    我仍然不知道为什么旧版本不起作用。


    我在virtualbox托管的虚拟机中设置了一个mysql服务器,我可以使用命令行mysql客户端或mysql workbench在主机上成功连接它。

    但我无法使用具有相同ip和端口的mysql jdbc连接器连接到它。

    我将主机和vm与nat和端口转发的mysql服务器3306连接到主机的9936端口。

    我用来测试连接的java代码:

    String url = "jdbc:mysql://127.0.0.1:9936/test";
    Class.forName ("com.mysql.jdbc.Driver").newInstance();
    Connection conn = DriverManager.getConnection(url, "usr", "pwd");
    

    这是错误:

    Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
    
    The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    

    这真的很奇怪,因为我可以成功telnet到它并使用我能找到的任何mysql客户端连接到它但是java代码不起作用!


    更新2014 09 30

    我尝试了以下步骤,但没有工作:

    1. 在主机和客户端计算机上禁用防火墙
    2. 将mysql服务地址绑定到0.0.0.0
    3. 确保mysql不会跳过网络
    4. 确保在'%'上启用并授予连接到mysql的帐户域
    5. 这是当前状态:

      虚拟机设置: virtualbox settings

      我可以使用mysql客户端成功连接到它: mysql client success

      但是简单的jdbc代码会引发错误: jdbc error


      添加证明:

      mysql-connector-java 5.1.9: Error with 5.1.9

      mysql-connector-java 5.1.32: Success with 5.1.32

1 个答案:

答案 0 :(得分:2)

我在ArchLinux VM中有MariaDB(主机是Windows 8.1),网络配置摘录/etc/mysql/my.cnf如下:

#skip-networking
bind-address = 0.0.0.0

这是我的VirtualBox NAT配置:

enter image description here

我还授予了远程连接权限:

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION

通过此设置,我可以使用端口9936上的主机使用MySQL客户端进行连接。

这是我的gradle构建:

apply plugin: 'java'

apply plugin: 'application'
mainClassName = "Main"

repositories {
    mavenCentral()
}

dependencies {
    runtime 'mysql:mysql-connector-java:5.1.32'
}

这是根包中的Main.java

import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.SQLException;

public class Main {
    public static void main(String[] args) {
        try {
            String url = "jdbc:mysql://127.0.0.1:9936/test";
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            Connection conn = DriverManager.getConnection(url, "root", null);
            System.out.println("Connection successful!");
        } catch(Throwable t) {
            t.printStackTrace();
        }
    }
}

使用gradle run从主机运行它会产生:

Connection successful!

您可以使用完全相同的设置重现如此成功的情况吗?是否允许Java使用网络连接(例如,通过防火墙应用程序)?