Possible Workarounds: "General Network Error" using TCP/IP with .CommandTimeout = 0

F

Frank Jones

Possible Workarounds for some cases of "General Network Error" using TCP/IP
with .CommandTimeout = 0. Then General Network Error occurs in many
different situations so this very well may not apply to you. Just posting
this experience out here to newsgroups in case any others have same issue...

We had some .NET 1.1 ADO.NET code using Stored Procedure calling SQL Server
2000 sp3 on Windows 2003 server. We were getting a "General Network Error"
with TCP/IP protocol with the .CommandTimeout = 0. After a support call
with Microsoft on the issue, we were directed to a hotfix available via KB
823679. We were instructed to either run code using the .NET 1.1 framework
hotfix or to update all code to *not* use .CommandTimeout = 0, but to use
some other large value for long running queries other than 0. In general
the error was happenning very sporadically but one day things got into a
state in which it would happen about 95% of the time the stored procedure
was called from code so we put in a support call.

We were running code calling a stored procedure with code like this, with
TCP/IP connection via Network Library=dbmssocn:
(Note that changing to Named Pipes (Network Library=dbnmpntw) also stopped
the "General Network Error" from occurring.)

Sample Code:
------------
string connectionString = "Server=Server1;Database=Database1;"
connectionString += "integrated security=SSPI;Network Library=dbmssocn";
SqlConnection conn = new SqlConnection(connectionString);
conn.Open();
SqlCommand procMyStoredProc = new SqlCommand();
procMyStoredProc.CommandText = "procMyStoredProc";
procMyStoredProc.CommandTimeout = 0;
procMyStoredProc.CommandType = System.Data.CommandType.StoredProcedure;
procMyStoredProc.Connection = conn;
procMyStoredProc.ExecuteNonQuery();

Failure Message:
----------------
The failure occurred on .ExecuteNonQuery with an SqlException Thrown as
follows:
Message: General network error. Check your network documentation.
Number: 11
Procedure: ConnectionRead (recv())
Source: .Net SqlClient Data Provider

Code Stack Trace:
system.data.dll!System.Data.SqlClient.SqlConnection.OnError(System.Data.SqlC
lient.SqlException exception = {System.Data.SqlClient.SqlException},
System.Data.SqlClient.TdsParserState state = Broken)
system.data.dll!System.Data.SqlClient.SqlInternalConnection.OnError(System.D
ata.SqlClient.SqlException exception = {System.Data.SqlClient.SqlException},
System.Data.SqlClient.TdsParserState state = Broken)
system.data.dll!System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
system.data.dll!System.Data.SqlClient.TdsParser.ReadNetlib(int bytesExpected
= 8)
system.data.dll!System.Data.SqlClient.TdsParser.ReadBuffer()
system.data.dll!System.Data.SqlClient.TdsParser.ReadByteArray(byte[] buff =
<undefined value>, int offset = 1, int len = 3)
system.data.dll!System.Data.SqlClient.TdsParser.SkipBytes(long num = 4)
system.data.dll!System.Data.SqlClient.TdsParser.SkipValue(System.Data.SqlCli
ent._SqlMetaData md = {System.Data.SqlClient._SqlMetaData})
system.data.dll!System.Data.SqlClient.TdsParser.SkipRow(System.Data.SqlClien
t._SqlMetaData[] columns = {Length=14}, int startCol = 0)
system.data.dll!System.Data.SqlClient.TdsParser.SkipRow(System.Data.SqlClien
t._SqlMetaData[] columns = {Length=14})
system.data.dll!System.Data.SqlClient.TdsParser.Run(System.Data.SqlClient.Ru
nBehavior run = UntilDone, System.Data.SqlClient.SqlCommand cmdHandler =
{System.Data.SqlClient.SqlCommand}, System.Data.SqlClient.SqlDataReader
dataStream = <undefined value>)
system.data.dll!System.Data.SqlClient.SqlCommand.ExecuteReader(System.Data.C
ommandBehavior cmdBehavior = Default, System.Data.SqlClient.RunBehavior
runBehavior = UntilDone, bool returnStream = false)
system.data.dll!System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
ScratchConsole.exe!ScratchConsole.MainClass.Main(string[] args = {Length=0})
Line 34

TdsParser.ReadNetLib had an exception, not getting the bytes that were
expected.


TCP/IP Network Trace
--------------------
Looking at the Packet Trace, the failure case generated a packet with
ACK+RESET bits set (visible from both Client and SQL Server side). The
Client sends a packet to the Server with the following to TCP flag set:
TCP: Flags = 0x14 : .A.R..
(Note that the Network Trace is similar to what is described in KB Article
328476:
http://support.microsoft.com/?kbid=328476
however that KB article did not provide a solution for our problem, an in
this case the packet came from the Client to the Server while the KB 328476
was from Server to Client)

On the occasions when the code worked without the error, the packet trace
did not have an ACK+RESET packet. This is consistent with the KB 823769
disuccsion of the response broken into two packets and the provider (Client)
trying to close out the socket.


Work Arounds
------------
-Change the code on the SqlCommand object to set CommandTimeout to value
greater than zero (use a large value for infinite timeout instead of zero).
This was one recommended by the Microsoft Support person as possibly least
intrusive.

-Change the code to use Named Pipes instead of TCP/IP (Network
Library=dbnmpntw on the Connection String). There could be other problems
with Named Pipes however so may not work in all cases...

-Get the HotFix KB 823679 from microsoft described below and try that.

In our case all of the work arounds stopped the "General Network Error" from
occurring.


KB Article with HotFix
----------------------
The support person metioned that he thought the hotfix would sometime in the
future be included in a Service Pack for .NET Framework 1.1, but currently
it is available only as a hotfix.

Microsoft Knowledge Base Article - 823679
Fix: Multiple Fixes for SQL Server .NET Data Provider
....
"When the SQLCommand.CommandTimeout is set to zero, you expect an infinite
timeout. However, versions 1.1 and 1.0 of the SqlClient provider incorrectly
timeout when a response from SQL Server is broken into two packets.
Immediately upon receipt of the second packet, versions 1.1 and 1.0 of the
provider incorrectly timeout. The fix that is included in this article fixes
this issue so that the command will have an infinite timeout."

Note: Erland Sommarskog mentions this article KB 823679 in his post on SQL
Server Error handling because of corrections to ADO.NET SQL Server error
handling code. So there my be more reason to run this fix than just the
General Network Error.
http://www.sommarskog.se/error-handling-I.html#ADO.Net


Other URL of interest:
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top