Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What should I do to completely close the tcpClient connection with mcu?

I'm now working on a tcp socket connection to tcp server running in ESP32. It works fine for the communication, but I failed to close the connection. After searching for the solution on close/reset tcpClient, it seems that the proper way to close a tcpClient should be:

tcpClient.GetStream().Close();
tcpCLient.Close();

The example in msdn also use this method.

But unforunately, it cannot really close the connection. As checked in the mcu, the connection has not been closed. And it will not be closed even I close the application later. In this case, the mcu's tcp connection cannot be released, it cannot receive other connections. So, I think this should not be a proper solution to close the tcpClient.

If I did not execute above statement, and close the application directly, it can close the connection successfully. And the mcu's tcp connection is released. It seems that the there has something been done in application close which can really close the connection.

In some situation, I need to close the connection after some operation, and reconnect it. So, I cannot rely on the application close.

I have tried all the following methods in some different combination, but none of them can successfully release the tcpClient connection:

 tcpClient.Close(); 
 tcpClient.Client.Close();
 tcpClient.GetStream().Close();
 tcpClient.Client.Disconnect(true);
 tcpClient.Client.Disconnect(false);
 tcpClient.Dispose();
 tcpClient.Client.Dispose();
 tcpCLient = null;

Maybe it should be done with some of above commands in a proper sequence.

Does anyone know how I cannot close the connection by myself.

Thanks in advance.

like image 770
James MA Avatar asked Jul 06 '18 17:07

James MA


1 Answers

After studying the network packet using WireShark, it was found that the problem is due to the delay of sending RST with the code as suggested in MSDN:

tcpClient.GetStream().Close();
tcpCLient.Close();

There has no different even adding

tcpClient.LingerState = new LingerOptions(true, 0);

Because it will send FIN immediately, but not the RST after the Close method, it will be sent around 2 minutes later. Unfortunately, it won't be sent even you close the application after tcpClient close is issued.

enter image description here

If you close the application before closing the tcpClient, it will send the RST immedicately.

enter image description here

So that it can close the connection in server immediately.

After testing different combination of command, it was found that the following code can really close the connection immediately, but there will have another RST around 40 seconds later.

tcpClient.Client.Close();
tcpClient.Close();

enter image description here

Don't call tcpClient.GetStream().Close(); !!! It will cause the delay of RST.

I don't know if there has any impact closing the connection in this way, but this is the only way I can really close the connection immediately.

like image 88
James MA Avatar answered Nov 01 '22 10:11

James MA