Protocol error in TDS stream - error - c#

We have two servers. An application server and a SQL server.
When running this simple program from the application server:
static void Main(string[] args)
{
OleDbCommand cmd;
OleDbConnection cnn;
string connectionString = "Provider=SQLNCLI10;Integrated Security=SSPI;User ID=***;Password=***;Persist Security Info=False;Initial Catalog=MCS_BATCH;Data Source=CD6S01;Initial File Name=;";
string sql = "EXEC [msp].[MasterMSP] #BTYPE = N'B_PVM_KNN', #AC_KEY = NULL, #RUN_TS = '2014-05-02 17:29:31.1400555', #CHUNK_ID = 8794";
System.IO.StreamWriter file = new System.IO.StreamWriter("MasterMSP_output.txt");
cnn = new OleDbConnection(connectionString);
try
{
cnn.Open();
cmd = new OleDbCommand(sql, cnn);
try
{
OleDbDataReader reader = cmd.ExecuteReader();
int numberOfFields = reader.VisibleFieldCount;
StringBuilder sb = new StringBuilder();
while (reader.Read())
{
for (int i = 0; i < (numberOfFields - 1); i++)
{
file.Write(reader[i].ToString());
}
file.WriteLine("");
}
file.Close();
}
catch (Exception ex)
{
file.Write("Execption ex at : {0}", System.DateTime.Now);
file.Write(ex.Message.ToString());
Console.WriteLine("Exception ex time is : {0}", System.DateTime.Now);
throw;
}
cmd.Dispose();
cnn.Close();
}
catch (Exception exx)
{
file.Write("Execption exx at : {0}", System.DateTime.Now);
file.Write(exx.Message.ToString());
Console.WriteLine("Exception exx time is : {0}", System.DateTime.Now);
throw;
}
}
We get - after some time - a "Protocol error in TDS stream" error:
We ran a network trace, and we can see that the "TCP Window size" is decreasing after 10 mins and then it's sending a TCP Window size = 0 (close window).
This means that the SQL server can't send more data until it has gotten a update window size, bigger than 0, from the application server.(right?):
The SQL server is trying to send 1 byte keepalive, but the application server is never responding. (The problem is that the application server never raise TCP Windows Size again. At the end the application server is terminating the session.)
We except that it's the application server fault and it could be that the networks buffer is not being empty(flushed) anymore. The only thing the TCP stack can do is to close the TCP Windows Size until the application again empties the buffer - but it never does that.
Any hints, ideas on what the issue can be?
The problem actually came up in 3rd party program. This program is calling a stored procedure on the SQL server. So I just tried to reproduce the logic in a C# program and was able to reproduce the error.
Any help, ideas or comments are highly appreciated.
Thanks

Adding this to the connectionstring fixed the error: MARS Connection=True
Link

Related

Non-terminating program when trying to read and write from Microsoft Access database with C#

I am trying to read from a Microsoft Access database with C# with the below code.
static void getProducts()
{
string accessDBPath = #"C:\Users\...\dummydb.accdb";
string connectionString = #"Provider=Microsoft.ACE.OLEDB.16.0;Data Source=" + accessDBPath;
string strSQL = "SELECT * FROM Products";
try
{
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
connection.Open();
OleDbCommand command = new OleDbCommand(strSQL, connection);
OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine("product name = ...");
}
}
}
catch (OleDbException ex)
{
Console.WriteLine(ex.Message);
}
finally
{
Console.WriteLine("Finished");
}
}
I'm able to walk through the products table just fine (i.e., the stuff inside the while(reader.Read()){...} prints as expected), and the finally block prints as expected as well.
But after the function is done running, the program just never terminates, and the command line just freezes. When I try to force the program to quit at the end of my Main function with Environment.Exit(0);, I get hit with this error:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
The using clause should have automatically closed the database connection when I'm finished with it, but it seemingly behaves as if I hadn't, so I have no clue what's going on, and would appreciate any help.
EDIT: Copy-paste error, declared a variable twice.

C# Socket Listener (Server)

I have the below program that receives socket streams in form of XML and inserts them into SQL database. My problem is the following:
- When the program is launched in debug mode, all the xml streams are inserted successfully into the database.
- When it is launched normally (no debug mode), the program will insert one xml stream and miss the other (So if I had 20 streams, only 10 will be inserted).
What could be the error in this code?
client = Listener.AcceptTcpClient();
netstream = client.GetStream();
Status = "Connected to a client\n";
byte[] bytes = new byte[client.ReceiveBufferSize + 1];
netstream.Read(bytes, 0, Convert.ToInt32(client.ReceiveBufferSize));
// Return the data received from the client
string clientdata = System.Text.Encoding.ASCII.GetString(bytes);
Status="Client sent: " + clientdata ;
StorePolicy(clientdata);
Query = clientdata;
Query = Query.Replace("\0", "");
StorePolicy(Query);
Status="Received Query: " + Query;
StorePolicy("Received Query: " + Query);
netstream.Close();
client.Close();
///////////////insert into database/////////
try
{
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand Cmd = new SqlCommand();
string[] words = Query.Split(new[] { "</RECORD>" }, StringSplitOptions.None);
StorePolicy(Query);
foreach (string word in words)
{
if (!string.IsNullOrEmpty(word))
{
record = word.Replace("'", "''") + "</RECORD>";
StorePolicy(record);
StrQuery = "INSERT INTO SMSListenner(XMLText) VALUES ('" + record.Replace("'", "''") + "')";
Cmd = new SqlCommand(StrQuery, conn);
conn.Open();
Cmd.ExecuteReader();
conn.Close();
StorePolicy(StrQuery);
}
}
}
MSDN clearly says:
The TcpListener class provides simple methods that listen for and
accept incoming connection requests in blocking synchronous mode.
This means once one client is connected, it blocks every other client until your "poor man web server" finished with the stream. Other clients that wait in the queue might timeout in mean time. Mind yourself that you are doing a hell of a lot to process request. This means that you will block other clients for a significant amount of time.
Also, you have no exception handling, so one client can kill your entire "server".
My advice, if it's not a student's project to learn how sockets work, use proper web server with isolation between connections, and capable of processing multiple connections at the same time.

Server side error logging

I'm working on creating web application, which will host in IIS, which I plan to accept a lot of short time connections. Right now I'm working on error logging, and it turns out that it's not that clear how to do it.
For example my back-end sql server went down and 1000 clients which try to get responses from server each 10 minutes, will flood in the event log of the server 60000 events in 1 hour. Can anyone share his experience on how not to flood the event log on the server?
The code is close to this:
RequestHandler :
try {
SqlConnection con = new SqlConnection(...);
cmd.CommandText = "SELECT TOP FROM Foo WHERE Bar = `"Some`"";
con.Open();
cmd.Connection = con;
// convert data to instance
}
catch (SqlException ex)
{
Logger.WriteErrorEvent(ex)
}
// convert instance to response and send it back.
Thanks,
Jenia.
As in another post - the best solution is to use your own files for logging. And I recommend to use log4net for this. It will take a while to get started, but once you learn it you'll see how useful it is. It will allow you to set different logging levels so you can log only information you need at that time and change them on the fly.
Instead of logging to Event log, You need to create a file and write all your errors to that file. Something like the following method, and you can call this method whenever you get any exception.
public static void SaveLog(string exc)
{
FileStream objFS = null;
string strFilePath = "Exception.log";
if (!File.Exists(strFilePath))
{
objFS = new FileStream(strFilePath, FileMode.Create);
}
else
objFS = new FileStream(strFilePath, FileMode.Append);
using (StreamWriter Sr = new StreamWriter(objFS))
{
Sr.WriteLine(System.DateTime.Now.ToShortTimeString() + "---" + exc);
}
}

ODBC Connection Issues: Function Sequence error when executing anything

I've been tasked with a one time migration from a 4D database to our MSSQL structure. I've got a datasource set up in the ODBC administrator and I was able to connect to it without issues.
I 'reverse engineered' the schema in Visio so I can get a good visual of the relationships between the tables and plan out how I'm going to re-structure the 4D data to fit into our schema. I created a simple console application as this will be a one time run, and I'm able to make the connection to the data source, but as soon as I execute anything, the connection drops or is disabled.
System.Data.Odbc.OdbcConnection conn =
new System.Data.Odbc.OdbcConnection("Dsn=4D v12 datasource");
try
{
conn.Open();
Console.WriteLine("Status of Connection:" + conn.State.ToString());
//Here it says the connection to the DB is open and ready for action
Console.ReadLine();
//pause to visually confirm the connection is open
OdbcCommand com = new OdbcCommand("SELECT * FROM ATable", conn);
com.CommandType = CommandType.Text;
Console.Write(com.ExecuteNonQuery());
//Right here it blows up and closes the connection
}
I also tried to do something with data set and data adapter, but to no avail.
System.Data.Odbc.OdbcConnection conn = new System.Data.Odbc.OdbcConnection("Dsn=4D v12 datasource");
try
{
conn.Open();
Console.WriteLine("Status of Connection:" + conn.State.ToString());
Console.ReadLine();
OdbcCommand com = new OdbcCommand("SELECT * FROM ATable", conn);
com.CommandType = CommandType.Text;
//Also tried using data sets and data adapters
DataSet dsTest = new DataSet();
OdbcDataAdapter dataAdapter = new OdbcDataAdapter(com);
//but right at this line the connection suddenly disconnects
dataAdapter.Fill(dsTest);
}
catch (Exception e)
{
Console.WriteLine("Failure:" + e.Message.ToString());
// the exception message reads simply connection has been disabled.
Console.WriteLine("Status of Connection: " + conn.State.ToString());
Console.ReadLine();
}
finally
{
Console.Write("Closing connection.");
conn.Close();
Console.Write(".");
conn.Dispose();
Console.WriteLine(".");
Console.WriteLine("Connection Closed and Disposed");
Console.ReadLine();
}
I've tried to look for anyone experiencing this same difficulty, but the documentation I've found has been scarce and not very helpful in this specific regard. There is a good amount of information about executing queries on the 4D product, but not from across the digital divide. Anyone with experience please advise. Thanks for your time and for any help you may be able to give, avid reader.
Apparently the root cause of the issue was in the driver. Upon replacing the driver I got from the website with one sent from the proprietor, the connections ceased being disabled and all is working as intended.

Monitoring and SQL Server Connection by leaving the connection open

I'm trying to monitor an SQL Server database connection and I'm either having issues or it's behaving as designed.
I would like to do this:
Open Connection
Write "Open"
Leave it open for 1 minute (using System.Threading.Thread.Sleep)
If the connection drops during this time write "Down" to the console
Close the connection
Write "Closed" to the console
Repeat forever
So with my SQL Express service started I start my code I get
Open
Closed
Open
Closed
(with the appropriate amount of time between)
Then right after I see "Open" again I stop my SQL Express service the next few lines I get are still
Open
Closed
Open
Closed
Now if I restart my program while the SQL Express service is stopped then I get the proper exception.
Here is my code.
static void Main(string[] args)
{
//
string strConnectionString;
string strEnabled;
string strPath;
strConnectionString = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\GlobalNet Direct\\DatabaseMonitor", "ConnectionString", false).ToString();
strEnabled = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\GlobalNet Direct\\DatabaseMonitor", "Enabled", false).ToString();
strPath = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\GlobalNet Direct\\DatabaseMonitor", "LogPath", false).ToString();
do
{
strEnabled = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\GlobalNet Direct\\DatabaseMonitor", "Enabled", false).ToString();
//System.Threading.Thread.Sleep(15000);
SqlConnection myConnection = new SqlConnection(strConnectionString);
try
{
myConnection.Open();
Console.WriteLine(myConnection.State.ToString());
System.Threading.Thread.Sleep(1000);
}
catch (Exception)
{
Console.WriteLine("Down");
}
try
{
if (myConnection.State.ToString() == "Open")
{
myConnection.Close();
System.Threading.Thread.Sleep(1000);
Console.WriteLine(myConnection.State.ToString());
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}while (strEnabled == "True");
}

Categories