How to check if the TcpClient connection is closed?

I am playing with TcpClient and I am trying to figure out how to make the Connected property false when the connection is disconnected.

I tried to do

NetworkStream ns = client.GetStream(); ns.Write(new byte[1], 0, 0); 

But it still will not show me if TcpClient is disabled. How would you do this using TcpClient?

+25
c # sockets tcpclient networkstream
Sep 07 '09 at 3:41
source share
7 answers

I would not recommend you try writing only for socket testing. And do not relay the .NET Connected property either.

If you want to know if the remote endpoint is active, you can use TcpConnectionInformation:

 TcpClient client = new TcpClient(host, port); IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties(); TcpConnectionInformation[] tcpConnections = ipProperties.GetActiveTcpConnections().Where(x => x.LocalEndPoint.Equals(client.Client.LocalEndPoint) && x.RemoteEndPoint.Equals(client.Client.RemoteEndPoint)).ToArray(); if (tcpConnections != null && tcpConnections.Length > 0) { TcpState stateOfConnection = tcpConnections.First().State; if (stateOfConnection == TcpState.Established) { // Connection is OK } else { // No active tcp Connection to hostName:port } } client.Close(); 

See also:
TcpConnectionInformation on MSDN
IPGlobalProperties on MSDN
Description of TcpState Approves
Netstat on Wikipedia




And here it is like an extension method on TcpClient.

 public static TcpState GetState(this TcpClient tcpClient) { var foo = IPGlobalProperties.GetIPGlobalProperties() .GetActiveTcpConnections() .SingleOrDefault(x => x.LocalEndPoint.Equals(tcpClient.Client.LocalEndPoint)); return foo != null ? foo.State : TcpState.Unknown; } 
+33
Oct 31 '13 at 12:15
source share

As far as I know / remember, there is no way to check if a socket is connected, except for reading or writing to it.

I did not use TcpClient at all, but the Socket class will return 0 from the Read call if the remote end was disconnected gracefully. If the remote end does not turn off gracefully [I think], you get a timeout exception, you cannot remember the type of apology.

Using code like ' if(socket.Connected) { socket.Write(...) } creates a race condition. You better just call socket.Write and handle exceptions and / or disconnections.

+7
Sep 07 '09 at 8:40
source share

@Uriel's answer works fine for me, but I needed to encode it in C ++ / CLI, which was not entirely trivial. Here is the (roughly equivalent) C ++ / CLI code, with a few reliability checks added for a good grade.

 using namespace System::Net::Sockets; using namespace System::Net::NetworkInformation; TcpState GetTcpConnectionState(TcpClient ^ tcpClient) { TcpState tcpState = TcpState::Unknown; if (tcpClient != nullptr) { // Get all active TCP connections IPGlobalProperties ^ ipProperties = IPGlobalProperties::GetIPGlobalProperties(); array<TcpConnectionInformation^> ^ tcpConnections = ipProperties->GetActiveTcpConnections(); if ((tcpConnections != nullptr) && (tcpConnections->Length > 0)) { // Get the end points of the TCP connection in question EndPoint ^ localEndPoint = tcpClient->Client->LocalEndPoint; EndPoint ^ remoteEndPoint = tcpClient->Client->RemoteEndPoint; // Run through all active TCP connections to locate TCP connection in question for (int i = 0; i < tcpConnections->Length; i++) { if ((tcpConnections[i]->LocalEndPoint->Equals(localEndPoint)) && (tcpConnections[i]->RemoteEndPoint->Equals(remoteEndPoint))) { // Found active TCP connection in question tcpState = tcpConnections[i]->State; break; } } } } return tcpState; } bool TcpConnected(TcpClient ^ tcpClient) { bool bTcpConnected = false; if (tcpClient != nullptr) { if (GetTcpConnectionState(tcpClient) == TcpState::Established) { bTcpConnected = true; } } return bTcpConnected; } 

Hope this helps someone.

+2
Mar 19 '15 at 17:48
source share

I created this function and worked for me to check if all the client is connected to the server.

 /// <summary> /// THIS FUNCTION WILL CHECK IF CLIENT IS STILL CONNECTED WITH SERVER. /// </summary> /// <returns>FALSE IF NOT CONNECTED ELSE TRUE</returns> public bool isClientConnected() { IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties(); TcpConnectionInformation[] tcpConnections = ipProperties.GetActiveTcpConnections(); foreach (TcpConnectionInformation c in tcpConnections) { TcpState stateOfConnection = c.State; if (c.LocalEndPoint.Equals(ClientSocket.Client.LocalEndPoint) && c.RemoteEndPoint.Equals(ClientSocket.Client.RemoteEndPoint)) { if (stateOfConnection == TcpState.Established) { return true; } else { return false; } } } return false; } 
+2
Oct 19 '15 at 8:15
source share

The solution of Peter Wone and uriel is very nice. But you also need to check the remote endpoint, as you can have multiple open connections to your local endpoint.

  public static TcpState GetState(this TcpClient tcpClient) { var foo = IPGlobalProperties.GetIPGlobalProperties() .GetActiveTcpConnections() .SingleOrDefault(x => x.LocalEndPoint.Equals(tcpClient.Client.LocalEndPoint) && x.RemoteEndPoint.Equals(tcpClient.Client.RemoteEndPoint) ); return foo != null ? foo.State : TcpState.Unknown; } 
+1
May 29 '17 at 12:22
source share

In my case, I sent some command to the server (running on a virtual machine on the same computer) and waiting for a response. However, if the server unexpectedly stopped while waiting, I did not receive any notifications. I tried the possibilities offered by other posters, but it didn’t work either (he always said that the server is still connected). For me, the only thing that works is to write 0 bytes to the stream:

 var client = new TcpClient(); //... open the client var stream = client.GetStream(); //... send something to the client byte[] empty = { 0 }; //wait for response from server while (client.Available == 0) { //throws a SocketException if the connection is closed by the server stream.Write(empty, 0, 0); Thread.Sleep(10); } 
0
Mar 29 '17 at 14:16
source share

Try it works for me

 private void timer1_Tick(object sender, EventArgs e) { if (client.Client.Poll(0, SelectMode.SelectRead)) { if (!client.Connected) sConnected = false; else { byte[] b = new byte[1]; try { if (client.Client.Receive(b, SocketFlags.Peek) == 0) { // Client disconnected sConnected = false; } } catch { sConnected = false; } } } if (!sConnected) { //--Basically what you want to do afterwards timer1.Stop(); client.Close(); ReConnect(); } } 

I used the Timer because I wanted to check the connection status at a regular interval and not in LOOP with the listen code [I felt this slows down the sending process)

-one
Dec 25 '11 at 19:11
source share



All Articles