2

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.)

Dominique
  • 16,450
  • 15
  • 56
  • 112
  • Seeking recommendations for books, tools, software libraries, and more is off-topic on Stack Overflow. https://softwarerecs.stackexchange.com/ may help with tools – Thomas Weller Jan 13 '23 at 13:16
  • Confused by the question. You've hit your breakpoint because you have a connected socket, therefore there is a service accepting the connection on the other side. What is the problem you'd like to solve? – Spanners Jan 13 '23 at 13:16
  • 2
    @Spanners: he'd expect to find `TCP 10.1.13.200:whatever 10.1.0.160:50001` in the output, which - well isn't exactly matching the title of the question – Thomas Weller Jan 13 '23 at 13:17
  • @Spanners: I have opened a TCP socket, but in "netstat", I didn't see it. So I started debugging (thinking I would not reach that line in source code). So, it came to me as a surprise that I reached that line in source code while "netstat" told me there is no TCP socket established. – Dominique Jan 13 '23 at 13:18
  • @ThomasWeller: You are right, that was what I was expecting. Oh, and please don't close my question, as if I were asking for tools. As far as I know, "netstat" is a reliable commandline command for helping TCP socket programming (quod non :-) ). – Dominique Jan 13 '23 at 13:19
  • Related: https://stackoverflow.com/a/40876467/480982 – Thomas Weller Jan 13 '23 at 13:20
  • @ThomasWeller: sorry. I've replaced "netstat -aon" by "netstat -qon" and the result is equal. – Dominique Jan 13 '23 at 13:23
  • For most socket APIs I'm familiar with the `.Connected` property doesn't mean what you want it to mean. It doesn't mean you are currently still connected, it just means that the socket at some point in the past transitioned through the CONNECTED state. I don't know how .Net does sockets however, and .Net documentation is garbage. You find out the peer closed the socket when you do a read or write operation on that socket. – President James K. Polk Jan 13 '23 at 13:30
  • 1
    The only reliable way is sending a packet to the destination. – shingo Jan 13 '23 at 13:49
  • @shingo: ... which is exactly what I would like to avoid needing :-) – Dominique Jan 13 '23 at 13:59
  • 1
    @Dominique I don't think you can. Even worse: I don't think that would be physically possible unless both peers are connected via the same cable (and protocols would support it). – Fildor Jan 13 '23 at 14:08

1 Answers1

2

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.

Evk
  • 98,527
  • 8
  • 141
  • 191