I am trying to connect to Oracle database on a remote server (on cloudapp) using an ssh key pair authentication method. I can connect to the server with this code.
PrivateKeyFile keyFile = new PrivateKeyFile(#"D:\ssh.ppk");
var keyFiles = new[] { keyFile };
var username = "Admin";
var methods = new List<AuthenticationMethod>();
methods.Add(new PrivateKeyAuthenticationMethod(username, keyFiles));
var con = new ConnectionInfo("abc.xyz.net", 22, username, methods.ToArray());
using (var client = new SshClient(con))
{
client.Connect();
if (client.IsConnected)
{
var portForwarded = new ForwardedPortLocal("127.0.0.1", 3306, "127.0.0.1", 3306);
client.AddForwardedPort(portForwarded);
portForwarded.Start();
var connectionString = "DATA SOURCE=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=3306)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ABC_DB)));PASSWORD=myPassword;USER ID=myUsername";
//var connectionString = "DATA SOURCE=127.0.0.1:3306/ABC_DB;PASSWORD=myPassword;USER ID=myUsername";
using (OracleConnection conn = new OracleConnection(connectionString))
{
//conn.Open();
using (OracleCommand com = new OracleCommand("SELECT * FROM Table_Name", conn))
{
com.CommandType = CommandType.Text;
DataSet ds = new DataSet();
OracleDataAdapter da = new OracleDataAdapter(com);
da.Fill(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
}
}
client.Disconnect();
}
else
{
Console.WriteLine("Client cannot be reached...");
}
}
When I try to connect to the database it throws an exception packet checksum failure at the line da.Fill(ds);.
Can you please help me if you know what settings need to be changed, where.
Thanks in advance.
12569, 00000, "TNS:packet checksum failure"
Cause: The data received is not the same as the data sent.
Action: Attempt the transaction again. If the error is persistent, turn on tracing and reexecute the operation.
There must be mismatch on the tcp packet between server and client. You have to enable tracing on both sites, server and client.
Contact Network Administrators to fix packet problem on the basis of trace information.
References:
Tracing Error Information for Oracle Net Services
Getting ORA-12569: TNS:Packet Checksum Failure While Trying To Connect Through Client. (Doc ID 257793.1)
Related
I'm using a C# program to connect to a database and display data in a grid (TableFromMySql).
I installed my program on a PC that sits on the same network as the database. Ping is okay, but my program fails to connect, it reaches the catch statement and shows me "No connection to DB" error.
private void SQLMethod(string query)
{
try
{
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
connection.Open();
using (MySqlCommand cmdSel = new MySqlCommand(query, connection))
{
DataTable dt = new DataTable();
MySqlDataAdapter da = new MySqlDataAdapter(cmdSel);
da.Fill(dt);
TableFromMySql = dt.DefaultView;
if (TableFromMySql.Count == 0)
System.Windows.MessageBox.Show("No results.", "INFO", MessageBoxButton.OK, MessageBoxImage.Error);
}
connection.Close();
}
}
catch
{
System.Windows.MessageBox.Show("No connection to " + serverIP, "ERROR", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
Connection string is a string value:
private const string connectionString =
"SERVER=IP;" +
"PORT=3306;" +
"DATABASE=db;" +
"UID=root;" +
"PASSWORD=password;";
A few notes:
IP is the actual ip address of the DB, can't post it.
Connecting to the DB using HeidiSQL from that PC works fine.
I also checked the same code on my local PC with an Ubuntu VM running MySQL Server docker container and the code worked.
To create the installation file I used the Visual Studio Installer extension.
Any ideas?
So after a long time I found the answer. I added to the connection string "SslMode=None" and the problem was solved.
Installed Plesk on my VS. After this I can't setup SSH-tunnel to get data from other server-database. Using SSH.NET with below code. (This code works locally). Configured to allow communication for port 3306 in Plesk firewall. Any suggestions on how to solve this issue?
Error:
[SocketException (0x271d): An attempt was made to access a socket in a
way forbidden by its access permissions]
Code:
DataTable dt = new DataTable();
string IP = "ssh.xxxxxxxx.xxx";
string Username = "xxxxxxxxxx";
string password = "xxxxxxxxxx";
var connInfo = new Renci.SshNet.PasswordConnectionInfo(IP, Username, password);
using (var sshClient = new Renci.SshNet.SshClient(connInfo))
{
sshClient.Connect();
if (sshClient.IsConnected)
{
Renci.SshNet.ForwardedPortLocal port =
new Renci.SshNet.ForwardedPortLocal("127.0.0.1", 3306, "xxxxxxxx", 3306);
sshClient.AddForwardedPort(port);
port.Start();
using (MySqlConnection con = new MySqlConnection("SERVER=127.0.0.1;PORT=3306;UID=xxxxxx;PASSWORD=xxxxxxx;DATABASE=xxxxxxx; convert zero datetime=True"))
{
string tmpsql = "Select fname,lname,username FROM tbluser Where id=#id";
using (MySqlCommand cmd = new MySqlCommand(tmpsql, con))
{
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
cmd.Parameters.AddWithValue("id", MySqlDbType.Int16).Value = UserID;
da.Fill(dt);
}
}
}
sshClient.Disconnect();
}
The local port which you are trying to forward is most probably already used by another application (like a local MySQL database server).
Use another port. Or even better, let the system pick any free local port:
var port = new ForwardedPortLocal("127.0.0.1", "dbserver.example.com", 3306);
client.AddForwardedPort(port);
port.Start();
var connectionString =
$"SERVER={port.BoundHost};PORT={port.BoundPort};" +
"UID=xxxxxx;PASSWORD=xxxxxxx;DATABASE=xxxxxxx; convert zero datetime=True";
using (MySqlConnection con = new MySqlConnection(connectionString))
{
// ...
}
Related: C# SSH tunnel Postgres database connection
I've tried to create remote MySql connection via ssh tunnel forwardedport.
The sshClient connection OK.
ForwardedPort starts OK.
When I try to connect with MysqlConnection it throws System.Net.IO.IOException with the message "The handshake failed due to an unexpected packet format"
The port is OK 100% sure because other native app(eg HeidiSQL) can connect if i create this port with my app.
PrivateKeyFile file = new PrivateKeyFile(rsaFile);
client = new SshClient(host, port, username, file);
forwardBoundHost = "127.0.0.1";
forwardBoundPort = 33306;
forwardHost = "127.0.0.1";
forwardPort = 3306;
port = new ForwardedPortLocal(forwardBoundHost, forwardBoundPort, forwardHost, forwardPort);
if(this.response != null){
port.RequestReceived += response;
}
client.Connect();
client.AddForwardedPort(port);
port.Exception += port_Exception;
port.Start();
if (port.IsStarted)
{
cb = new MySqlConnectionStringBuilder()
{
AllowBatch = true,
Server = this.host,
Port = this.port,
UserID = this.dbuser,
Password = this.dbpassword,
Database = this.database,
SslMode = MySqlSslMode.Required,
Keepalive = 60,
ConnectionProtocol = MySqlConnectionProtocol.Tcp,
CharacterSet = "utf8"
};
cb.ConnectionProtocol = MySqlConnectionProtocol.Tcp;
MySqlConnection connection = new MySqlConnection(cb.GetConnectionString(true));
MySqlCommand cmd;
MySqlDataReader reader;
try
{
Console.WriteLine("Mysql client conn");
connection.Open();
}
cmd = connection.CreateCommand();
cmd.CommandText = queryString;
cmd.Prepare();
Array myp = new Array[param.Length];
int i = 0;
foreach (String oneParam in param)
{
myp.SetValue(new MySqlParameter(oneParam, MySqlDbType.String), i);
i++;
}
cmd.Parameters.AddRange(myp);
reader = cmd.ExecuteReader();
}
catch (Exception e)
{
//Logger(e.ToString());
throw (e);
}
finally
{
if (connection.State == System.Data.ConnectionState.Open)
connection.Close();
}
return reader;
I found a solution for my problem. Because of using the Forwarded Port, the default port 3306 changed to 33306 in connection string, so (and tell me if i'm wrong) the MySQLClient changed the SslMode from None (in my first attempts it was not set) to any of Required or Preffered etc...
Tried to set it to MySqlSslMode.None and it worked like charm :) finally!
Using SSH.Net and MySqlClient
Connect to server with SSHClient(ConnectionInfo)
Start ForwardedPortLocal(127.0.0.1, 33306, 127.0.0.1, 3306)
Connect MySql WITHOUT ANY SSLMode (MySqlSSLMode.None)
Here is the code!
cb = new MySqlConnectionStringBuilder()
{
AllowBatch = true,
Server = this.host,
Port = this.port,
UserID = this.dbuser,
Password = this.dbpassword,
Database = this.database,
SslMode = MySqlSslMode.None,
Keepalive = 60,
ConnectionProtocol = MySqlConnectionProtocol.Tcp,
CharacterSet = "utf8"
};
cb.ConnectionProtocol = MySqlConnectionProtocol.Tcp;
MySqlConnection connection = new MySqlConnection(cb.GetConnectionString(true));
MySqlCommand cmd;
MySqlDataReader reader;
try
{
Console.WriteLine("Mysql client conn");
connection.Open();
cmd = connection.CreateCommand();
cmd.CommandText = queryString;
cmd.Prepare(); ....
If you need any help let me know.
I have multiple databases (30+) that are used at clinics and setup automatically via the license software they use. So each database is named the same and use the same port, the only thing that changes is the IP. That being said, I am using the following code to attempt to run a query against them individually. However, when I change out the IP and run the script again it is returning the results from the previous server.
using System;
using System.Diagnostics;
using System.Data.OleDb;
namespace ConnectionTest
{
class Program
{
static void Main(string[] args)
{
using (OleDbConnection conn = new OleDbConnection("Provider=SAOLEDB.10;LINKS=tcpip(host=X.X.X.X,PORT=2638);ServerName=EAGLESOFT;Integrated Security = True; User ID = dba; PWD = sql"))
{
try
{
conn.Open();
using (OleDbCommand cmd = new OleDbCommand("SELECT tran_num, provider_id, tran_date FROM transactions WHERE tran_date LIKE '2015-11-23%'", conn))
{
using (OleDbDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine("{0}|{1}|{2}", reader.GetValue(0).ToString(), reader.GetValue(1).ToString(), reader.GetValue(2).ToString());
}
}
}
}
catch (Exception connerr) { Debug.WriteLine(connerr.Message); }
conn.Close();
}
if (Debugger.IsAttached)
{
Console.ReadLine();
}
}
}
}
I don't see any reason why you would be getting previous results, here. Are you running multiple instances of this code at the same time? Are you manually changing the IP address in your code each time? I assume the "Transactions" object is an actual table and not something being generated on-the-fly?
With just a tiny bit of modification, you could pass the IP address as a command line parameter:
static void Main(string[] args)
{
string ip, port = null;
for (int i = 0; i < args.Length; i++)
{
if (args[i].StartsWith("/i:"))
ip = args[i].Substring(args[i].IndexOf(':') + 1);
else if (args[i].StartsWith("/p:"))
port = args[i].Substring(args[i].IndexOf(':') + 1);
}
// Default the port value to 2638 (since I have no idea if that changes).
if (string.IsNullOrEmpty(port))
port = "2638";
string connStr = string.Format("Provider=SAOLEDB.10;LINKS=tcpip(host={0},PORT={1});ServerName=EAGLESOFT;Integrated Security = True; User ID = dba; PWD = sql", ip, port);
using (OleDbConnection conn = new OleDbConnection(connStr))
{
try
{
conn.Open();
if (conn.State != System.Data.ConnectionState.Open)
// You could also implement a WHILE loop with a small delay (~1200ms) and try again to open the connection, with a counter to "fail" after a certain number (like 3) of attempts.
throw new Exception("Unable to open connection to database.");
using (OleDbCommand cmd = new OleDbCommand("SELECT tran_num, provider_id, tran_date FROM transactions WHERE tran_date LIKE '2015-11-23%'", conn))
using (OleDbDataReader reader = cmd.ExecuteReader())
while (reader.Read())
Console.WriteLine("{0}|{1}|{2}", reader.GetValue(0).ToString(), reader.GetValue(1).ToString(), reader.GetValue(2).ToString());
}
catch (Exception connerr)
{ Debug.WriteLine(connerr.Message); }
finally
{ conn.Close(); }
}
if (Debugger.IsAttached)
{
Console.ReadLine();
}
}
First and foremost (for testing purposes, that is) I would probably try removing the ServerName parameter since you're already providing an IP address explicitly.
So your connection string would be:
Provider=SAOLEDB.10;LINKS=tcpip(host=X.X.X.X,PORT=2638);Integrated Security = True; User ID = dba; PWD = sql
Similar to ORA files, DSNs, etc, it almost sounds like you have a server alias configured for EAGLESOFT that may be overwriting the IP preference in your testing.
Make sure you change EagleSoft as well as IP. You have to pass the IP address as an arg[]. Modify code as below to allow the IP to change
string host = "X.X.X.X";
string conStr = string.Format("Provider=SAOLEDB.10;LINKS=tcpip(host={0},PORT=2638);ServerName=EAGLESOFT;Integrated Security = True; User ID = dba; PWD = sql", host);
using (OleDbConnection conn = new OleDbConnection(conStr))
I programmed a Windows service which gets strings from a client using TCP socket and saves them to a database. It's connect and no have error send/receive. But in first, service can't connect to SQL Server database :
string sql = "Select * from [Commands] Where [cName]='" + _cName + "'";
pr = new Persistance();
using (var item = pr.sqlDataReader(sql))
{
return new Commands
{
cID = item.GetInt32(0),
cName = item.GetString(1),
cType = item.GetInt32(2),
msgID = item.GetInt32(3)
};
}
My persistance class;
public SqlDataReader sqlDataReader(string sqlCommand)
{
connection = new SqlConnection(connectionString);
connection.Open();
return new SqlCommand(sqlCommand, connection).ExecuteReader();
}
What I miss I can't understand. it write in catch side :
An established connection was aborted by the software in your host machine
First of all, you should use parametrized queries to avoid SQL injection attacks - so you'll need to modify your SELECT statement:
string sql = "Select * from [Commands] Where [cName]= #cname";
and you'll need to somehow define that parameter and set its value - not sure what your Persistance class is that you're using - in raw ADO.NET, it would be something like:
SqlCommand cmd = new SqlCommand(sql, connection);
cmd.Parameters.Add("#cname", SqlDbType.VarChar, 100).Value = _cName;
Next, when using a SqlDataReader, you must call .Read() on that data reader to actually get the data:
using (var item = pr.sqlDataReader(sql))
{
// call .Read() on the SqlDataReader - and this *COULD* return multiple rows!
// Not just one - it could return many - so you'll need to handle that somehow.....
while (item.Read())
{
Commands cmd = new Commands
{
cID = item.GetInt32(0),
cName = item.GetString(1),
cType = item.GetInt32(2),
msgID = item.GetInt32(3)
};
// store all those "Commands" retrieved into a list or something and return them
}
}