[c#] How to properly and completely close/reset a TcpClient connection?

What is the correct way to close or reset a TcpClient connection? We have software that communicates with hardware but sometimes something goes wrong and we are no longer to communicate with it, until we restart the software.

I have tried forcing TcpClient.Close() and even setting it to null but that doesn't work. Only a complete restart of the software works.

Suggestions?


I can't use the using keyword because TpcClient is only defined in one location, but used throughout the library. (And there is only one connection at any given time)

It's a library that handles communication. The software itself can call the ResetConnection() method of the Controller class (which represents the hardware).

It currently looks like

if (tcpClient != null)
{
    tcpClient.Close();
    tcpClient = null;
}

Now from what I've read here I should use tcpClient.Dispose() instead of " = null"

I'll give that a try and see if it makes a difference.

This question is related to c# .net tcp

The answer is


Use word: using. A good habit of programming.

using (TcpClient tcpClient = new TcpClient())
{
     //operations
     tcpClient.Close();
}

The correct way to close the socket so you can re-open is:

tcpClient.Client.Disconnect(true);

The Boolean parameter indicates if you want to reuse the socket:

Disconnect method usage


Closes a socket connection and allows for re-use of the socket:

tcpClient.Client.Disconnect(false);

Except for some internal logging, Close == Dispose.

Dispose calls tcpClient.Client.Shutdown( SocketShutdown.Both ), but its eats any errors. Maybe if you call it directly, you can get some useful exception information.


Despite having all the appropriate using statements, calling Close, having some exponential back off logic and recreating the TcpClient I've still been seeing issues where the application cannot recover the TCP connection without an application restart. It keeps failing with a System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.

But there is an option LingerState on the TcpClient that appears it may have solved the issue (might not know for a few months as my own hardware setup only fails about that often!). See MSDN.

// This discards any pending data and Winsock resets the connection.
LingerOption lingerOption = new LingerOption(true, 0);

using (var tcpClient = new TcpClient 
       {SendTimeout = 2000, ReceiveTimeout = 2000, LingerState = lingerOption })
   ...

Use word: using. A good habit of programming.

using (TcpClient tcpClient = new TcpClient())
{
     //operations
     tcpClient.Close();
}

Use word: using. A good habit of programming.

using (TcpClient tcpClient = new TcpClient())
{
     //operations
     tcpClient.Close();
}

Given that the accepted answer is outdated and I see nothing in the other answers regarding this I am creating a new one. In .Net 2, and earlier, you had to manually close the stream before closing the connection. That bug is fixed in all later versions of TcpClient in C# and as stated in the doc of the Close method a call to the method Close closes both the connection and the stream

EDIT according to Microsoft Docs

The Close method marks the instance as disposed and requests that the associated Socket close the TCP connection. Based on the LingerState property, the TCP connection may stay open for some time after the Close method is called when data remains to be sent. There is no notification provided when the underlying connection has completed closing.

Calling this method will eventually result in the close of the associated Socket and will also close the associated NetworkStream that is used to send and receive data if one was created.


Have you tried calling TcpClient.Dispose() explicitly?

And are you sure that you have TcpClient.Close() and TcpClient.Dispose()-ed ALL connections?


Except for some internal logging, Close == Dispose.

Dispose calls tcpClient.Client.Shutdown( SocketShutdown.Both ), but its eats any errors. Maybe if you call it directly, you can get some useful exception information.


Given that the accepted answer is outdated and I see nothing in the other answers regarding this I am creating a new one. In .Net 2, and earlier, you had to manually close the stream before closing the connection. That bug is fixed in all later versions of TcpClient in C# and as stated in the doc of the Close method a call to the method Close closes both the connection and the stream

EDIT according to Microsoft Docs

The Close method marks the instance as disposed and requests that the associated Socket close the TCP connection. Based on the LingerState property, the TCP connection may stay open for some time after the Close method is called when data remains to be sent. There is no notification provided when the underlying connection has completed closing.

Calling this method will eventually result in the close of the associated Socket and will also close the associated NetworkStream that is used to send and receive data if one was created.


Closes a socket connection and allows for re-use of the socket:

tcpClient.Client.Disconnect(false);

Except for some internal logging, Close == Dispose.

Dispose calls tcpClient.Client.Shutdown( SocketShutdown.Both ), but its eats any errors. Maybe if you call it directly, you can get some useful exception information.


Have you tried calling TcpClient.Dispose() explicitly?

And are you sure that you have TcpClient.Close() and TcpClient.Dispose()-ed ALL connections?


The correct way to close the socket so you can re-open is:

tcpClient.Client.Disconnect(true);

The Boolean parameter indicates if you want to reuse the socket:

Disconnect method usage


Have you tried calling TcpClient.Dispose() explicitly?

And are you sure that you have TcpClient.Close() and TcpClient.Dispose()-ed ALL connections?


Use word: using. A good habit of programming.

using (TcpClient tcpClient = new TcpClient())
{
     //operations
     tcpClient.Close();
}

Despite having all the appropriate using statements, calling Close, having some exponential back off logic and recreating the TcpClient I've still been seeing issues where the application cannot recover the TCP connection without an application restart. It keeps failing with a System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.

But there is an option LingerState on the TcpClient that appears it may have solved the issue (might not know for a few months as my own hardware setup only fails about that often!). See MSDN.

// This discards any pending data and Winsock resets the connection.
LingerOption lingerOption = new LingerOption(true, 0);

using (var tcpClient = new TcpClient 
       {SendTimeout = 2000, ReceiveTimeout = 2000, LingerState = lingerOption })
   ...

Have you tried calling TcpClient.Dispose() explicitly?

And are you sure that you have TcpClient.Close() and TcpClient.Dispose()-ed ALL connections?


Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to .net

You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to use Bootstrap 4 in ASP.NET Core No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Update .NET web service to use TLS 1.2 EF Core add-migration Build Failed What is the difference between .NET Core and .NET Standard Class Library project types? Visual Studio 2017 - Could not load file or assembly 'System.Runtime, Version=4.1.0.0' or one of its dependencies Nuget connection attempt failed "Unable to load the service index for source" Token based authentication in Web API without any user interface

Examples related to tcp

What does "app.run(host='0.0.0.0') " mean in Flask What is the difference between HTTP 1.1 and HTTP 2.0? Sending a file over TCP sockets in Python Telnet is not recognized as internal or external command How to open port in Linux adb connection over tcp not working now Understanding [TCP ACKed unseen segment] [TCP Previous segment not captured] How do I debug error ECONNRESET in Node.js? Differences between TCP sockets and web sockets, one more time Is SMTP based on TCP or UDP?