Enabling Keepalive on ODBC client for MSSQL Server - sql-server

I have got step by step information on how to enable/set/modify the keep alive option on MSSQL Server side. But, how to do the same while using ODBC client to connect with MSSQL Server? This is mainly used to close the socket on client side and start reconnecting.
I came across an option called "Connect Timeout
-or-
Connection Timeout", in connection string, which disconnects if there is no connection after that timeout. But i hope TCP keep alive does more than this.
Couple of options would do for me,
1) Is there a keepalive option that could be added in connection string (similar to postgres)?
2) How to get the client socket fd, which connects with the MSSQL Server, (without using OS commands) so that, i could use setsockopt API and enable keep alive

Related

JDBC failed connectivity to MSSQL server after TCP handshake

Attempting to make a JDBC connection from client (Windows Server 2012) to server (MSSQL Server 2012 SP2 hosted on Windows Server) results in this error:
Connection Timeout Expired.  The timeout period elapsed while
attempting to consume the pre-login handshake acknowledgement.  This
could be because the pre-login handshake failed or the server was
unable to respond back in time.  The duration spent while attempting
to connect to this server was - [Pre-Login] initialization=273;
handshake=29736;  (Microsoft SQL Server, Error: -2)
Packet trace analysis:
After the TCP handshake, the client sends a TDS pre-login packet to the server, but with the bytes representing the version all set to 0.  The server doesn't respond (though the protocol indicates the server MUST respond in some way), so the client re-transmits and eventually the client sends a TCP reset to the server. 
Additional details:
Port 1433 is open on both the client and server.
No network or software is filtering traffic from client to server.
Connectivity to the server is successful from other machines on different domains using the same connection string.
Connectivity is successful from client to server at the data link layer (tested using Data Link Editor).
TCP/IP is enabled for IPv4 and IPv6 on both the client and server.
TLS is enabled on both servers.
We have tried 3 different JDBC drivers using Squirrel SQL & MSSQL Server Management Studio.  All provide the same error.  The drivers refer to the correct DLLs.
Tracert from client to server completes successfully.
We have tried modifying the connection string to force trust of the server certification, force encryption, increase connection timeout value to several minutes, etc.
.NET 4.5 is used on the client, but .NET 4.5 is also used on other machines that can successfully connect to the server.
What could be the issue? I'm out of ideas.

Where is the cache of SQL Server Browser service for resolving Instance name's port number?

From here:
When SQL Server clients request SQL Server resources, the client network library sends a UDP message to the server using port 1434. SQL Server Browser responds with the TCP/IP port or named pipe of the requested instance.
Apparently when UDL or SSMS used for connecting remotely to SQL Server instance name, the query for resolving the instance name's port number store's somewhere in client machine.
I tested this by two client machines. When the 1434 UDP port was open first machine could connect to SQL Server instance name. Then I closed the port and tried again with that machine. The first client still could connect without the port being open. Then I tried with second machine but it couldn't connect.
I just wondering how and where this caching takes place?
Client APIs like SqlClient use connection pooling by default to avoid the overhead of name resolution, physical network connection, and authentication every time a connection is opened. When the initial connection is closed, the connection is added to a connection pool where it can be reused the next time another connection with the same attributes is opened. The client API in that case simply retrieves and unused connection from the pool avoiding the significant overhead of establishing the physical connection.
With a named instance, connection pooling also avoids the need to query the SQL Server Browser service every time a connection is opened so this explains your observations. I suspect if you exit and re-launch the application after blocking UDP port 1434, the SQL connection for the named instance will fail due to the failed SQL Server Browser data gram query during the initial connection open.

Sql resets my pooling connections after idle time

I'm using a client pc and i'm connecting via tcp/ip into a local database server. For some reason, after my connection will be idle for a while, then Sql keep alive is checking my tcp connection if it's still active. If the time when keep alive is checking my connection and tcp/ip traffic is high or other reasons, then it resets my connection inside pooling. So the result is that if my connection will be reset ,the first connection which client pc will try to run, it will get exception "TCP Provider, error: 0 - No connection could be made because the target machine actively refused it
" or " Server closed the connection" or something like this. This happens cause client pc will try to connect in a session which there is not exist inside sql pooling. I have set min pool size =10. But i still have the same problem.
after keep alive time
Here is my connection string
Data Source = xxx.xxx.xxx.xxx;Min Pool Size=20; Initial Catalog = WiOrder; user id = xxxx; password = 1234;Connection Timeout=5;
SQL Server does not terminate connections. What you are seeing is being done by the .Net driver on your client machine and is completely normal and expected behavior.
Please see:
https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/sql-server-connection-pooling#removing-connections

How to find socket fds opened by a process in windows

I have a client process running in windows (win 7/win 2008 server). The task is to enable keepalive for one of the socket it opened to get connected with a server.
To make this connection i'm using windows API (connection to MSSQL server), from which i was unable to retrieve the socket fd it created.
1) What is the way to retrieve all the socket fds opened by a windows process (non python method, as the binary is a C++ based)
2) Is there any way to retrieve socket fd from the handle returned by the windows API SQLAllocHandle or SQLDriverConnect
Thanks
You can't (AFAIK) and shouldn't (not supported) try to modify this on the client. SQL Server has a server-side configuration setting that controls this:
Keep Alive
This parameter (in milliseconds) controls how often TCP attempts to verify that an idle connection is still intact by sending a KEEPALIVE packet. The default is 30000 milliseconds.
https://technet.microsoft.com/en-us/library/ms190771(v=sql.105).aspx

If I can ping my DB server, is my SQL Server connection guaranteed to work?

If I can ping my DB server, is my SQL Server connection guaranteed to work?
I am using a default connection string in my code.
My program runs fine locally but overseas sites are having issues and I am wondering if SQL might be using a TCP or UDP port that is still blocked.
Here is the connection string "Data Source=xxxx.xxxx.com; Initial Catalog = xxxxx; User ID=xxxxx;password=xxxxx"
As far as I understand your question you are asking whether ICMP "ping" packet which returns guarantees you can open a connection on a particular TCP port? The answer is NO. It is also not the other way around - "ping" packets might be blocked by a firewall.
telnet xxxx.xxxx.com 1433 might be a better indicator.
No. The SQL Server Service must at least be running on the server for any mssql connections to work. The server itself can be up - running and pingable without the SQL Server Serice running.
You might also need to check whether the TCP/IP protocol is enabled using SQL Server Configuration Manager. Even when MSSQLSvc is running, it might not respond to remote requests.

Resources