Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is writing zero bytes to a network stream a reliable way to detect closed connections?

I'm working on an application where a client connects with a TCP connection which then triggers an amount of work that may potentially take a lot of time to complete. This work must be cancelled if the user drops the TCP connection.

Currently, what I'm doing is starting up a timer that periodically checks the networks streams connectivity by doing this:

// stream is a Stream instance
var abort = false;
using (new Timer(x => {
   try
   {
      stream.Write(new byte[0], 0, 0);
   }
   catch (Exception)
   {
      abort = true;
   }
}, null, 1000, 1000))
{
   // Do expensive work here and check abort periodically
}

I would have liked to read the CanWrite, CanRead or Connected but they report the last status of the stream. Is writing zero bytes a reliable way of testing connectivity, or can this itself cause issues? I cannot write or read any real data on the stream since that would mess up the client.

like image 388
Dervall Avatar asked Aug 01 '12 09:08

Dervall


1 Answers

Let's just say that I have known it to work, decades ago, but there is no intrinsic reason why it should. Any of the API layers between you and the TCP stack is entitled to suppress the call to the next layer down, and even if it gets all the way into the stack it will only return an error if:

  1. It checks for network errors before checking for zero length, which is implementation-dependent, and
  2. There already was a network error, caused by some previous operation, or an incoming RST.

If you're expecting it to magically probe the network all the way to the other end, it definitely won't.

like image 147
user207421 Avatar answered Nov 15 '22 08:11

user207421