views:

308

answers:

2

I'm implementing a basic HTTP Server in C++, using boost::asio.

As I process each request, I write out the data in chunks, asychronously. If at any point I knew the client was no longer connected, I'd like to abort the processing, e.g. there's no point continuing to build results up to send out if the client is no longer there.

I think this has already been asked here a few times, e.g.:

http://stackoverflow.com/questions/685951/how-can-i-check-if-a-client-disconnected-through-winsock-in-c

But I reading them I'm still not sure what a good approach here is.

  • Can I try to read from the client socket? (Even knowing that the HTTP client at the other end isn't going to be sending any data)
  • Because I'm writing asynchronously (using boost::asio::async_write), I don't seem to receive feedback if the client is no longer there
+1  A: 

If the client disconnects, you should have your asynchronous writes fail with an appropriate error code. When your completion handler is invoked with an error, abort processing then.

bdonlan
A: 

There are 3 things to consider (though how that's done using boost, I don't know)

  • Detect a clean shutdown from the client. This is done by a read() from the client. a read returning 0 means the other end have closed the connection, if you're implementing http pipelining you likely have to keep reading from the client anyway.

  • Detect an unclean shutdown on the client, a write() should eventually fail, a read() will error as well

Then there's the cases inbetween where the client just vanishes or is a maliciously slow reader/writer You'll have to implement;

  • Timeouts. if there's no activity for a period of time you should throw away the connection. This applies you writing something to the client as well. Any network read or write that doesn't implement a timeout is severely broken anyway, and will end up leaking resources (Just think users closing their notebook, pulling the cable, NAT gateways silently throwing away tcp connections , malicious users not reading and blocks the TCP transfer, etc.). If you have no control over the async write process, you'll get in trouble here.
nos
You suggested doing a read() from the client. It seems to me there are three states: client is connected but hasn't written anything; client is connected by has written something; client is disconnected. If read() returns 0, will I know for sure that this means the client is disconnected rather than the client is connected but hasn't written anything?
Alex Black
If the client disconnected cleanly, then write() operations will also be able to report disconnects as well.
Remy Lebeau - TeamB
The client could close its writing endpoint if it knows it is only going to be receiving data and not writing anymore. If you rely on read() to detect a disconnect, you could detect a false disconnect when the client is actually still connected and able to receive.
Remy Lebeau - TeamB
Generally that's allowed for TCP connections, not in HTTP though.
nos