SQLConnection use randomly namedpipes instead of tcp - c#

SQLConnection use randomly namedpipes(445) instead of tcp(1433). The namedpipes port is blocked by our firewall but not the tcp. This only happens when trying to connect to one of our sql servers. Most of the time the application use the tcp but randomly is trying to use namedpipes port. Our sql connection is very simple and we doesn't do something fancy with it.
We don't want to hardcoded the tcp port on our connection string. We already try and it's fixed the problem. The problem only appears during the last week and our web application that try to connection is live for a while.
Why the sql connection sometimes trying to connect with 445 instead of 1433? Is it a bug introduced by .net latest updates or does the server can dictate the next port to use?
UPDATE 2016-09-23 11:00
Here's a sample of the code we are using to connect
string connectionString = "Data Source=SERVERNAME;Initial Catalog=DATABASE;uid=username;pwd=mypass;MultipleActiveResultSets=True";
using (SqlConnection connection = new SqlConnection(connectionString))
{
try {
connection.Open();
…

We don't want to hardcoded the tcp port on our connection string.
You don't necessarily have to put the IP address/Port# in your connection string.
BUT, you can force the network protocol in the connection string.
Network Library=DBMSSOCN;
https://www.connectionstrings.com/define-sql-server-network-protocol/
But when I've had random named-pipes issues that slow performance, I make the connection string as "specific" as possible. Which is...specify the network-library and the ip address and the port number.
By the way, I really really hope you are not actually coding your connection string in compiled code, and the below is not your actual code.
string connectionString = "Data Source=SERVERNAME;Initial Catalog=DATABASE;uid=username;pwd=mypass;MultipleActiveResultSets=True";
APPEND:
You can "fish" around this registry-setting on the problem machines.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo\
I would look specifically if DSQUERY is set or not set.
https://support.microsoft.com/en-us/kb/328306
Check the protocol that is specified in the following registry subkey:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo\DSQUERY This value typically reflects the settings in the CNU, but sometimes
it does not.
If the value is DBNETLIB, it uses one of the protocols in
the enabled protocols list of the CNU. If a specific protocol is
listed, that protocol is used instead.
If this is the issue.........ultimately, any other program can alter this value. So you don't have full-control. Again, the better solution is to put the network-library in the connection string, so "outside forces" cannot change the game on you, mid-game.
The reason I know this is because I got burnt at a client site......some other program changed the DSQUERY value one about 1/3 of the client machines (that also was using our application) and our application performance went to a crawl. Aka, some other company....did something to make our application performance horrible. So instead of fighting it, I put in the network library in our connection-string to permanently address the issue.

You never mention if this connection is made from end user PCs, a web server, other db servers, etc. However, whether named pipes is used or TCP as the primary protocol is a setting on the PC that creates the connection. This can be configured using SQL Server Native Client Configuration and it can also be overriden in the connection string.
To change the default protocol or the protocol order for client computers
In SQL Server Configuration Manager, expand SQL Server Native Client Configuration, right-click Client Protocols, and then click Properties.
In the Enabled Protocols box, click Move Up or Move Down, to change the order in which protocols are tried, when attempting to connect to SQL Server. The top protocol in the Enabled Protocols box is the default protocol.
To configure a client to use TCP/IP
In SQL Server Configuration Manager, expand SQL Server Native Client Configuration, right-click Client Protocols, and then click Properties.
In the Enabled Protocols box, click the up and down arrows to change the order in which protocols are tried, when attempting to connect to SQL Server. The top protocol in the Enabled Protocols box is the default protocol.
See Configure Client Protocols

Why the sql connection sometimes trying to connect with 445 instead of
1433? Is it a bug introduced by .net latest updates or does the server
can dictate the next port to use?
It is the client rather than the server that determines the protocol order. Most client drivers will use TCP/IP first and then fall back on named pipes when the TCP connection fails. Below is the relevant excerpt from the documentation that applies to SqlClient as well.
For example, if a client computer has both TCP and Named Pipes
available, and the order is:
TCP
Named Pipes
When the client computer tries to make a TCP
connection to the server and the connection attempt returns a non-zero
return code, the client transparently tries a connection by using the
next protocol in the list, which is Named Pipes. In this scenario, the
client cannot make a TCP connection; however, the client successfully
makes a Named Pipes connection.
Note
The client does not receive an error that indicates the first protocol failed.
If the client application uses the second protocol, and it also
returns an error, an error is returned to the client.
So to answer your question more directly, named pipes is attempted only because the initial TCP connection failed. The client error message indicates a named pipes connection failure but that's just a side effect of the initial TCP connection failure. The root cause based on your symptoms is an intermittent database or network connectivity problem, not at all related to using named pipes.

what about the server side?
what I would double check in SQL Server instance configuration on the servers:
which protocols are enabled on the servers behaving as expected
which protocols are enabled on the server that's showing that unexpected behaviour
my guess is that the 'broken' server has named pipes enabled while other servers does not so when the .NET client is choosing the connection protocol sometimes makes the wrong choice.
that's a wild guess because I don't know how the choice of the connection protocol is made by .NET...

I had this issue. I suspect it was either AppLocker restrictions OR running the app off a network drive that caused this. I copied the app locally and resolved the applocker restrictions and now it seems to use the correct port.
I received no errors and even forcing parameters with the connection string did not work to fix it. Now it uses port 1433 as expected.

Related

How to connect my .net application to SQL Server via internet

I have created a C# application with a login form (I use SQL Server database and SSMS). The database is on my PC, when I run the program on another PC which is in the same network as mine, everything works fine, but when I connect one of the laptops on another network, an error occurs: "The path wasn't found".
Is it possible to connect with the server remotely, via internet or something,
without having to be on the same network?
I already have:
Opened tcp and udp ports
Allowed SQL Server ports in Windows Firewall
Added an inbound rule for tcp (port 1433) and udp (port 1434)
Allowed remote connections
Here is my connection string:
Data Source=<server name>;Initial Catalog=Name;User ID=Minko;Password=Password1
This is not a programming question, but a Networking one.
To have a server reachable in the internet, is a costly mater. The static IP adress alone will cost a pretty penny, never mind actuall hardware.
On a small/no budget, VPN is perhaps the only way. Via VPN you can connect two local Networks (the home side of the Routers), allowing devices to talk as if they were physically in the same network.
No change to the programm is nessesary. If it works local, it works over VPN. The network classes do not care if the target is on the same computer, the same Switch or the Voyager probes.
The user will have to connect to teh VPN endpoint you have to provide - and usually can provide for cheap with any decent Router.
First off you should definitely change that PW.
Also - you make the comment that you are trying to use the same program to connect from a different network - implying that you haven't changed the IP address...
Are you sure you're using your public IP address? (Not your local network one that will start with 10. / 172. / 192.
Make sure you're using your public IP address... if you do this even if you're on the same network it will treat it as if you're not. It seems to me like you're still trying to use the local network's IP.
If it persists make sure you can reach the PC itself: ping ip-of-host in Powershell.
Connecting C# with SQL Server Database in a Local Area Network (LAN)
Try these steps one by one :
1- Find your public IP address using ( www.whatismyip.com ) for example.
2- Check that you can connect to the database using the public IP. To do that go to SSMS, and in the server name try to use IP-address only, or "IP-address\[instance-name]. If doesn't work, then you have to fix this first. Check this: https://dba.stackexchange.com/questions/62165/i-cant-connect-to-my-servers-sql-database-via-an-ip-address
3- When step 2 works, then you can use the "IP-Address\[instance-name]" in the connection string.

Is there any way we can connect to document databases like Visual Fox pro using TCP tunneling

My requirement is I should be able to connect to different databases which are not in my network. I should be able to establish connection by passing Firewall,Nat.We have tried Ngrok which is a tool that can in be installed in machine out of my network.Using ngrok we can expose either a tcp or http port to Public access by passing their firewall and Nat rules.
Using ngrok i am able to establish connection to sql server in some third party network by creating TCP tunnel on SQL server default port 1433.for this i need to install Ngrok in that server.
I tried connecting those file based databases(Ex: Visual Fox Pro) using ngrok by exposing TCP 21(FTP protocol) but not successful.
How i can connect to Document databases which are files based using or any other tool?I am not able to find way to connect them by exposing some http or tcp port for tunneling?
There is no way, you can bypass "their" firewall rules if you don't:
Control of the server running the firewall;
Have found a bug in the firewall;
If you can control the server, then you just need to expose any port that is not-denied (like port 80, if the port is occupied try another) and pass traffic to the database port (like 1433). This is not what ngrok is doing btw. For that you could use:
netcat / socat, like so: netcat -L 127.0.0.1:1433 -p 80 -vvv - this means: listen on port 80 and when someone connects to port 80 from outside, establish a connection to port 1433 on an forward traffic there. See more: http://www.devkb.org/linux/115-TCP-tunnel-port-forwarding-using-Netcat
ssh tunneling (if you need encryption);
Note, traditionally tunneling is used to bypass "local firewalls". So for example you have a company policy not allowing certain websites (I had companies not allowing SO itself!) but that have linux servers that are exempt from this policy. An SSH proxy is helpful in this scenario.
As you said. VFP is a file based database. However, there is a driver from Sybase called ADS (Advantage Database Server). You can use that to access VFP data as a service based C/S database.
Since you are saying ngrok which is a Go based utility, you might as well create microservices, REST based webAPI ... to do CRUD operations on VFP database. Doing something like that with Go is much easier than doing with another language IMHO (at least it was the language I found to be easiest for this kind of job, not only its network capabilities but also its concurrency support rocks).
We can not connect file based databases through TCP tunneling. Because TCP tunneling works on port permission and file based databases works on access to file path.

Connect via GPRS to SQL Instance without public IP

We have the following set up:
Windows Mobile Device with GPRS connection
Windows Server PC with SQL Server 2012
VPN Network where both devices contained (the cell carrier routes certain IPs inside VPN)
Status:
With the above set up I can ping directly from the mobile device to Windows server internal IP via GPRS.
Question:
Can I create connection to SQL server from my Mobile using the server's internal IP?
My con string is:
"Data Source =xxxxxxxx,1433;Initial Catalog=xxxxx;Integrated Security=SSPI;User id=xxxxx;Password=xxxxx;Connect Timeout=15"
EDIT:
More Questions:
How can I implement it if yes
What are the pros and cons in accordance to David's comment
If you have a VPN and can ping the internal server then you can connect directly to SQL Server using the normal data access libraries available in the .Net Framework. Having said that, I would strongly advise against it. It's much preferable to have a middle tier service that interfaces between the mobile device and the database. Here are some reasons (off the top of my head) why this is better:
Mobile connections are inherently unstable and SQL connections are not great at handling that.
Having a service means you don't even need a VPN as it can be public facing (with relevant security of course).
If in future you decide to move form SQL Server to DocumentDB/Azure/carrier pigeon, then you need to update every single mobile device to cope with the change. If you have an intermediate server, you can just update that.
If database schema changes, you may break all of your client applications in one go.
Your middle tier can do other useful things like caching, logging etc.

Creating database using sql script and sqlserverdbconnection class gives error ["Failed to connect to server"]

SqlServerDBConnection.SqlServerDBConnection objDB = new SqlServerDBConnection.SqlServerDBConnection();
string s = SqlServerDBConnection.SqlServerDBConnection.ConnStr;
bool isDBCreated = objDB.CheckAndCreateDatabase(txtSrvName.Text.ToString(), txtUid.Text.ToString(), txtPwd.Text.ToString(), txtDB.Text.ToString());
Above is the code which is being used to connect , create database using script.
Above code runs awesome on local but when I deployed on client side it shows
"Failed to connect to server".
SqlConnection is working fine.
Sql server is connecting database to server.
Is there any code issue or security issue?
I'm not sure there's enough information in the question to resolve the issue but some ideas:
Check if firewall is allowing connections on TCP 1433.
To test it you can simply telnet the server from outside the network to simulate your client's conneciton:
telnet {SERVER_IP} 1433
If you can't connect, check out this document: Configure the Windows Firewall to Allow SQL Server Access
Make sure SQL Server is set to accept remote connections
In SSMS, right click on the server name and select Properties. In Connections section make sure "Allow remote connections to this server" is checked.
Having that said, I wouldn't recommend connecting to database directly from the client site. A better approach would be putting a web API in front of the database and let the API handle database operations. Since the data will be transmitted over HTTP/HTTPS firewall configurations and network access wouldn't be an issue. But it's just a long-term solution obviously.
Hope this helps a bit.

Testing for network connectivity via opening a database connection

I have a little .net 2.0 systray app (C#) that checks for network connectivity periodically. It does this by attempting to open a connection to a SQL-Server instance on another computer (and selection a row from a table). The application saves documents created by another process to a database when it finds a connection. It is going to be used in environments with potentially dicey wireless networks.
In testing our QA team is using ipconfig /Release on the DB server (hosting a Sql-Server 2005 DB). What we found was that the application continued to claim it was network connected, because it kept right on successfully opening connections to SQL Server. I found the systray app's behavior erratic in my own testing using ipconfig /release.
At the suggestion of our not-currently-present network guy I changed my own internal testing (app hosted on a VM, connecting to DB on my workstation) to instead turn off the VM network connection. This produces the expected behavior (the systray app can't find a network connection). The QA guys are a little leery about my suggested that they do the same, and I need to put them at ease.
It was suggested to me that SQL Server was using named-pipes to accept incoming connections. If Named Pipes and TCP/IP are enabled, does this invalidate the ipconfig /release test?
I don't really know much about networking. Named-pipes, according to what I have read, sounds like it is designed for use between applications on the same server. But it can be used for intranet communications?
Is there something else going on here that I an unware of? Something about how ipconfig /release works
For your application, I would only use TCP/IP communication protocol. Although SQL Server supports other communication protocols such as named pipes, I would disable them on your server so it only accepts TCP/IP connections. This is least amount of overhead and should perform the best regardless of connection speed.
Named pipes is a different protocol then TCP/IP, so releasing the IP address may not effect named pipe communication in any way (Sounds like it is).
On the SQL Server machine, put TCP/IP as the number 1 protocol and disable named pipes. The have QA re-run the test. I have included a configuration screen shot for reference.

Categories