I'm developing a C# application, working with TCP sockets.
While debugging, I arrive in this piece of source code:
if ((_socket!= null) && (_socket.Connected))
{
Debug.WriteLine($"..."); <= my breakpoint is here.
return true;
}
In my watch-window, the value of _socket.RemoteEndPoint
is:
_socket.RemoteEndPoint {10.1.0.160:50001} System.Net.EndPoint {...}
Still, in commandline, when I run netstat -aon | findstr /I "10.1.0.160"
, I just see this:
TCP 10.1.13.200:62720 10.1.0.160:3389 ESTABLISHED 78792
TCP 10.1.13.200:63264 10.1.0.160:445 ESTABLISHED 4
=> the remote endpoint "10.1.0.160:50001" is not visible in netstat
result.
As netstat
seems not reliable for testing TCP sockets, what tool can I use instead?
(For your information: even after having run further, there still is no "netstat" entry.)
CodePudding user response:
Documentation of Socket.Connected, says:
The value of the Connected property reflects the state of the connection as of the most recent operation. If you need to determine the current state of the connection, make a nonblocking, zero-byte Send call. If the call returns successfully or throws a WAEWOULDBLOCK error code (10035), then the socket is still connected; otherwise, the socket is no longer connected.
So if it returns true - socket has been "connected" some time in the past, but not necessary is still alive right now.
That's because it's not possible to detect if your TCP connection is still alive with certainly without contacting the other side in one way or another. The TCP connection is kind of "virtual", two sides just exchange packets but there is no hard link between them. When one side decides to finish communication - it sends a packet and waits for response from the other side. If all goes well two sides will both agree that connection is closed.
However, if side A does NOT send this close packet, for example because it crashed, or internet died and so on - the other side B has no way to figure out that connection is no longer active UNTIL it tries to send some data to A. Then this send will fail and now B knows connection is dead.
So if you really need to know if other side is still alive - then you have to send some data there. You can use keepalive which is available on TCP sockets (which basically does the same - sends some data from time to time). Or if you always write on this connection first (say other side is server and you do requests to it from time to time, but do not expect any data between those requests) - then just don't check if the other side is alive - you will know that when you will attempt to write next time.