简体   繁体   English

SSH 使用 C# 建立一个 MySQL 连接

[英]SSH tunneling a MySQL connection using C#

I was trying to use SSH tunneling to access my MySQL database using C# but I'm getting an exception我试图使用 SSH 隧道来使用 C# 访问我的 MySQL 数据库,但出现异常

Unable to connect to any of the specified MySQL hosts.无法连接到任何指定的 MySQL 主机。

I got this code with the help of this:我在这个帮助下得到了这个代码:
C# SSH tunnel to MySQL server C# SSH 隧道到 MySQL 服务器

Here is my code:这是我的代码:

PasswordConnectionInfo connectionInfo = new PasswordConnectionInfo("example.com", 2222, "username", "password");
connectionInfo.Timeout = TimeSpan.FromSeconds(30);

using (var client = new SshClient(connectionInfo))
{
    try
    {
        Console.WriteLine("Trying SSH connection...");
        client.Connect();
        if (client.IsConnected)
        {
            Console.WriteLine("SSH connection is active: {0}", client.ConnectionInfo.ToString());
        }
        else
        {
            Console.WriteLine("SSH connection has failed: {0}", client.ConnectionInfo.ToString());
        }

        Console.WriteLine("\r\nTrying port forwarding...");
        var portFwld = new ForwardedPortLocal(IPAddress.Loopback.ToString(),2222, "example.com", 3306); 
        client.AddForwardedPort(portFwld);
        portFwld.Start();
        if (portFwld.IsStarted)
        {
            Console.WriteLine("Port forwarded: {0}", portFwld.ToString());
    Console.WriteLine("\r\nTrying database connection...");

 DBConnect dbConnect = new DBConnect("127.0.0.1", "database", "username", "password", "3306");
    int id =  dbConnect.Count("table");
    MessageBox.Show(id + " count ");
            }
            else
            {
                Console.WriteLine("Port forwarding has failed.");
            }

        }
        catch (SshException ex)
        {
            Console.WriteLine("SSH client connection error: {0}", ex.Message);
        }
        catch (System.Net.Sockets.SocketException ex1)
    {
        Console.WriteLine("Socket connection error: {0}", ex1.Message);
    }

}
private MySqlConnection connection;

private string server;
public string Server
{
    get
    {
        return this.server;
    }
    set
    {
        this.server = value;
    }
}

private string database;
public string Database
{
    get
    {
        return this.database;
    }
    set
    {
        this.database = value;
    }
}

private string uid;
public string Uid
{
    get
    {
        return this.server;
    }
    set
    {
        this.server = value;
    }
}

private string password;
public string Password
{
    get
    {
        return this.password;
    }
    set
    {
        this.password = value;
    }
}

private string port;
public string Port
{
    get
    {
        return this.port;
    }
    set
    {
        this.port = value;
    }
}

//Constructor
public DBConnect(string server, string database, string uid, string password, string port = "3306")
{
    this.server = server;

    this.database = database;
    this.uid = uid;
    this.password = password;
    this.port = port;

    Initialize();
}

//Initialize values
private void Initialize()
{
    string connectionString;
    connectionString = "SERVER=" + server + ";" + "DATABASE=" + database + ";" + "UID=" + uid + ";" + "PASSWORD=" + password + ";";
    connection = new MySqlConnection(connectionString);
}


//open connection to database
private bool OpenConnection()
{
    try
    {
        connection.Open();
        Console.WriteLine("MySQL connected.");
        return true;
    }
    catch (MySqlException ex)
    {
        //When handling errors, you can your application's response based on the error number.
        //The two most common error numbers when connecting are as follows:
        //0: Cannot connect to server.
        //1045: Invalid user name and/or password.
        switch (ex.Number)
        {
            case 0:
                Console.WriteLine("Cannot connect to server.  Contact administrator");
                break;

            case 1045:
                Console.WriteLine("Invalid username/password, please try again");
                break;

            default:
                Console.WriteLine("Unhandled exception: {0}.", ex.Message);
                break;

        }
        return false;
    }
}

//Close connection
private bool CloseConnection()
{
    try
    {
        connection.Close();
        return true;
    }
    catch (MySqlException ex)
    {
        Console.WriteLine(ex.Message);
        return false;
    }
}

//Count statement
public int Count(string tableName)
{
    string query = "SELECT Count(*) FROM " + tableName;
    int Count = -1;

    //Open Connection
    if (this.OpenConnection() == true)
    {
        //Create Mysql Command
        MySqlCommand cmd = new MySqlCommand(query, connection);

        //ExecuteScalar will return one value
        Count = int.Parse(cmd.ExecuteScalar() + "");

        //close Connection
        this.CloseConnection();

        return Count;
    }

    return Count;

}

The output that I got in my console is:我在控制台中得到的输出是:

Trying SSH connection...
A first chance exception of type 'System.ObjectDisposedException' occurred in mscorlib.dll
A first chance exception of type 'System.ObjectDisposedException' occurred in System.dll
SSH connection is active: Renci.SshNet.PasswordConnectionInfo

Trying port forwarding...
Port forwarded: Renci.SshNet.ForwardedPortLocal
A first chance exception of type 'Renci.SshNet.Common.SshConnectionException' occurred in Renci.SshNet.dll

Trying database connection...
A first chance exception of type 'System.Net.Sockets.SocketException' occurred in System.dll
A first chance exception of type 'System.Net.Sockets.SocketException' occurred in MySql.Data.dll
A first chance exception of type 'MySql.Data.MySqlClient.MySqlException' occurred in MySql.Data.dll
A first chance exception of type 'MySql.Data.MySqlClient.MySqlException' occurred in MySql.Data.dll
 Error: 0 : Unable to connect to any of the specified MySQL hosts.
A first chance exception of type 'MySql.Data.MySqlClient.MySqlException' occurred in MySql.Data.dll
A first chance exception of type 'MySql.Data.MySqlClient.MySqlException' occurred in MySql.Data.dll
Unhandled exception: Unable to connect to any of the specified MySQL hosts..

UPATE:更新:

I have changed the port forwarding settings to :我已将端口转发设置更改为:

var portFwld = new ForwardedPortLocal("127.0.0.1", 1000, "127.0.0.1", 3306);

and I have changed my mySQL String to :我已将 mySQL 字符串更改为:

connectionString = "server=127.0.0.1;port=1000; UID=username; password=password; database=data1; charset=utf8;Allow User Variables=True";

I'm being connected to the ssh and my port is forwarded but I still can't connect to MySQL database, I'm getting an exception:我正在连接到 ssh 并且我的端口被转发,但我仍然无法连接到 MySQL 数据库,我收到一个异常:

A first chance exception of type 'System.IO.EndOfStreamException' occurred in MySql.Data.dll
A first chance exception of type 'MySql.Data.MySqlClient.MySqlException' occurred in MySql.Data.dll
A first chance exception of type 'MySql.Data.MySqlClient.MySqlException' occurred in MySql.Data.dll
 Error: 0 : Reading from the stream has failed.

You have to connect the MySQL to the bound port of the forwarding.您必须将 MySQL 连接到转发的绑定端口。 Ie to the 2222.即到 2222。

Or even more semantically correct, use portFwld.BoundPort .或者在语义上更正确,使用portFwld.BoundPort Equivalently, use portFwld.BoundHost .等效地,使用portFwld.BoundHost

DBConnect dbConnect = new DBConnect(portFwld.BoundHost, "database", "username", "password", portFwld.BoundPort);

Also note that it makes more sense to refer to the MySQL host as "localhost", rather than the "example.com", as the hostname is resolved on the server-side.另请注意,将 MySQL 主机称为“localhost”而不是“example.com”更有意义,因为主机名是在服务器端解析的。 And when on the server side, you typically won't connect to "example.com", but to a "localhost".在服务器端,您通常不会连接到“example.com”,而是连接到“localhost”。

var portFwld = new ForwardedPortLocal(IPAddress.Loopback.ToString(), 2222, "localhost", 3306); 

And of course you need to keep the SSH session open while you need the tunnel.当然,您需要在需要隧道时保持 SSH 会话打开。 So you have to connect to the DB within the using block:所以你必须在using块中连接到数据库:

using (var client = new SshClient(connectionInfo))
{
    ...
    client.Connect();
    ...
    portFwld.Start();
    ... 
    DBConnect dbConnect = new DBConnect(portFwld.BoundHost, "database", "username", "password", portFwld.BoundPort);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM