ASIO: Detecting broken connections
Hi, I was wondering how I can find out with ASIO whether a connection is broken. I have a client connected to the server that continuously streams data. I have to know at the client-side when the server has hung up. I tried to use an async_write and after 5 erroneous tries the running thread for the connection is terminated. Like this: void connection::run_thread() { while (!stopped()) { event_ptr e = fetch_event(); if (!stopped()) { int write_tries = 0; boost::asio::async_write(_socket, boost::asio::buffer(*e, e->length()), boost::bind(&connection::handle_write, this, boost::asio::placeholders::error, e, write_tries)); } } } void connection::handle_write(const boost::system::error_code &err, const event_ptr event, int write_tries) { if (write_tries == max_write_tries) stopped(true); // thread will break out of its main-loop after being notified if (stopped()) return; // no meaning to continue if (err) { // incremenent write_tries and retry async_write boost::asio::async_write(_socket, boost::asio::buffer(*event, event->length()), boost::bind(&connection::handle_write, this, boost::asio::placeholders::error, event, ++write_tries)); } } I think I am misunderstanding something. I thought that after a async_write the registered handler will be invoked. But the handler is NEVER invoked somehow, although data is send from the client to the server. I have the following questions: - Why is the handler never invoked? When is it supposed to be invoked? - What is the best way to find out a connection has been reset by the server? And client? Thanks alot, Andrej ___________________________________________________________ Yahoo! Mail is the world's favourite email. Don't settle for less, sign up for your free account today http://uk.rd.yahoo.com/evt=44106/*http://uk.docs.yahoo.com/mail/winter07.htm...
Andrej van der Zee
I was wondering how I can find out with ASIO whether a connection is broken. I have a client connected to the server that continuously streams data.
The canonical way to consistently detect broken TCP connections is to always have a read on the socket - it will return 0 on broken connection (in usual BSD sockets type reads - I would expect an appropriate error parameter set in ASIO). Since you're doing async operations this is pretty easy. Many times a write will only buffer the data (at the OS / TCP driver level), and an error is not detected until a later write (and if the client socket is in a "half shutdown" mode, it might be quite a while before the TCP keepalive timer pops and the socket is fully destroyed). This is absent special ASIO capabilities - if ASIO is doing a read "on your behalf", then the problem is the "not completely destroyed connection", which is an OS / TCP "feature" and nothing that ASIO can help with. I haven't found specific details relating to this in ASIO, but that may only be because I haven't read enough of the ASIO documentation. Chris K (or others), clarifications, corrections, or comments? Cliff
On 6/29/07, Cliff Green
Andrej van der Zee
wrote: I was wondering how I can find out with ASIO whether a connection is broken. I have a client connected to the server that continuously streams data.
The canonical way to consistently detect broken TCP connections is to always have a read on the socket - it will return 0 on broken connection (in usual BSD sockets type reads - I would expect an appropriate error parameter set in ASIO). Since you're doing async operations this is pretty easy.
Many times a write will only buffer the data (at the OS / TCP driver level), and an error is not detected until a later write (and if the client socket is in a "half shutdown" mode, it might be quite a while before the TCP keepalive timer pops and the socket is fully destroyed).
This is absent special ASIO capabilities - if ASIO is doing a read "on your behalf", then the problem is the "not completely destroyed connection", which is an OS / TCP "feature" and nothing that ASIO can help with. I haven't found specific details relating to this in ASIO, but that may only be because I haven't read enough of the ASIO documentation.
Chris K (or others), clarifications, corrections, or comments?
You test for a disconnection with Asio the same way you would with BSD sockets - you need to leave a long-running read operating going. Check out this post from the Asio-users mailing list: http://osdir.com/ml/lib.boost.asio.user/2006-11/msg00035.html Richard Cliff
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
What do you mean with a long-running read operation? In my setup, the client only writes data to the server. Should I start a thread with a synchronous asio::read on the socket? Or can I do this with an asio::asyn_read too? Is this possible while writing over the same socket at the same time? Thanks, Andrej --- Richard Dingwallwrote: > On 6/29/07, Cliff Green > wrote: > > > > Andrej van der Zee wrote: > > > I was wondering how I can find out with ASIO > whether a > > > connection is broken. I have a client connected > to the > > > server that continuously streams data. > > > > The canonical way to consistently detect broken > TCP > > connections is to always have a read on the socket > - it > > will return 0 on broken connection (in usual BSD > sockets > > type reads - I would expect an appropriate error > parameter > > set in ASIO). Since you're doing async operations > this is > > pretty easy. > > > > Many times a write will only buffer the data (at > the OS / > > TCP driver level), and an error is not detected > until a > > later write (and if the client socket is in a > "half > > shutdown" mode, it might be quite a while before > the TCP > > keepalive timer pops and the socket is fully > destroyed). > > > > This is absent special ASIO capabilities - if ASIO > is > > doing a read "on your behalf", then the problem is > the > > "not completely destroyed connection", which is an > OS / > > TCP "feature" and nothing that ASIO can help with. > I > > haven't found specific details relating to this in > ASIO, > > but that may only be because I haven't read enough > of the > > ASIO documentation. > > > > Chris K (or others), clarifications, corrections, > or > > comments? > > > You test for a disconnection with Asio the same way > you would with BSD > sockets - you need to leave a long-running read > operating going. > > Check out this post from the Asio-users mailing > list: > http://osdir.com/ml/lib.boost.asio.user/2006-11/msg00035.html > > Richard > > Cliff > > > > _______________________________________________ > > Boost-users mailing list > > Boost-users@lists.boost.org > > > http://lists.boost.org/mailman/listinfo.cgi/boost-users > > > > _______________________________________________ > Boost-users mailing list > Boost-users@lists.boost.org > http://lists.boost.org/mailman/listinfo.cgi/boost-users ___________________________________________________________ Yahoo! Answers - Got a question? Someone out there knows the answer. Try it now. http://uk.answers.yahoo.com/
On 6/29/07, Andrej van der Zeewrote: > > What do you mean with a long-running read operation? A read operation that waits indefinitely for any data the server might send. In my setup, the client only writes data to the > server. Should I start a thread with a synchronous > asio::read on the socket? You could, but... Or can I do this with an > asio::asyn_read too? async_read() is better because you don't have to spawn another thread :) Is this possible while writing > over the same socket at the same time? > Yes it is. Thanks, > Andrej I recommend you join the asio-users mailing list here: https://lists.sourceforge.net/lists/listinfo/asio-users I'm not sure if Chris checks boost-users that often, and he is much better at answering questions! Richard --- Richard Dingwall wrote: > > > On 6/29/07, Cliff Green > > wrote: > > > > > > Andrej van der Zee wrote: > > > > I was wondering how I can find out with ASIO > > whether a > > > > connection is broken. I have a client connected > > to the > > > > server that continuously streams data. > > > > > > The canonical way to consistently detect broken > > TCP > > > connections is to always have a read on the socket > > - it > > > will return 0 on broken connection (in usual BSD > > sockets > > > type reads - I would expect an appropriate error > > parameter > > > set in ASIO). Since you're doing async operations > > this is > > > pretty easy. > > > > > > Many times a write will only buffer the data (at > > the OS / > > > TCP driver level), and an error is not detected > > until a > > > later write (and if the client socket is in a > > "half > > > shutdown" mode, it might be quite a while before > > the TCP > > > keepalive timer pops and the socket is fully > > destroyed). > > > > > > This is absent special ASIO capabilities - if ASIO > > is > > > doing a read "on your behalf", then the problem is > > the > > > "not completely destroyed connection", which is an > > OS / > > > TCP "feature" and nothing that ASIO can help with. > > I > > > haven't found specific details relating to this in > > ASIO, > > > but that may only be because I haven't read enough > > of the > > > ASIO documentation. > > > > > > Chris K (or others), clarifications, corrections, > > or > > > comments? > > > > > > You test for a disconnection with Asio the same way > > you would with BSD > > sockets - you need to leave a long-running read > > operating going. > > > > Check out this post from the Asio-users mailing > > list: > > > http://osdir.com/ml/lib.boost.asio.user/2006-11/msg00035.html > > > > Richard > > > > Cliff > > > > > > _______________________________________________ > > > Boost-users mailing list > > > Boost-users@lists.boost.org > > > > > > http://lists.boost.org/mailman/listinfo.cgi/boost-users > > > > > > _______________________________________________ > > Boost-users mailing list > > Boost-users@lists.boost.org > > > http://lists.boost.org/mailman/listinfo.cgi/boost-users > > > > ___________________________________________________________ > Yahoo! Answers - Got a question? Someone out there knows the answer. Try > it > now. > http://uk.answers.yahoo.com/ > _______________________________________________ > Boost-users mailing list > Boost-users@lists.boost.org > http://lists.boost.org/mailman/listinfo.cgi/boost-users >
Thanks. I did some tests in the meanwhile and asio::asyn_read() does detect broken connections very well, without spanning an extra thread. Cheers, Andrej --- Richard Dingwallwrote: > On 6/29/07, Andrej van der Zee > wrote: > > > > What do you mean with a long-running read > operation? > > > A read operation that waits indefinitely for any > data the server might send. > > In my setup, the client only writes data to the > > server. Should I start a thread with a synchronous > > asio::read on the socket? > > > You could, but... > > Or can I do this with an > > asio::asyn_read too? > > > async_read() is better because you don't have to > spawn another thread :) > > Is this possible while writing > > over the same socket at the same time? > > > > Yes it is. > > Thanks, > > Andrej > > > > I recommend you join the asio-users mailing list > here: > https://lists.sourceforge.net/lists/listinfo/asio-users > > I'm not sure if Chris checks boost-users that often, > and he is much better > at answering questions! > > Richard > > --- Richard Dingwall wrote: > > > > > On 6/29/07, Cliff Green > > > > wrote: > > > > > > > > Andrej van der Zee > wrote: > > > > > I was wondering how I can find out with ASIO > > > whether a > > > > > connection is broken. I have a client > connected > > > to the > > > > > server that continuously streams data. > > > > > > > > The canonical way to consistently detect > broken > > > TCP > > > > connections is to always have a read on the > socket > > > - it > > > > will return 0 on broken connection (in usual > BSD > > > sockets > > > > type reads - I would expect an appropriate > error > > > parameter > > > > set in ASIO). Since you're doing async > operations > > > this is > > > > pretty easy. > > > > > > > > Many times a write will only buffer the data > (at > > > the OS / > > > > TCP driver level), and an error is not > detected > > > until a > > > > later write (and if the client socket is in a > > > "half > > > > shutdown" mode, it might be quite a while > before > > > the TCP > > > > keepalive timer pops and the socket is fully > > > destroyed). > > > > > > > > This is absent special ASIO capabilities - if > ASIO > > > is > > > > doing a read "on your behalf", then the > problem is > > > the > > > > "not completely destroyed connection", which > is an > > > OS / > > > > TCP "feature" and nothing that ASIO can help > with. > > > I > > > > haven't found specific details relating to > this in > > > ASIO, > > > > but that may only be because I haven't read > enough > > > of the > > > > ASIO documentation. > > > > > > > > Chris K (or others), clarifications, > corrections, > > > or > > > > comments? > > > > > > > > > You test for a disconnection with Asio the same > way > > > you would with BSD > > > sockets - you need to leave a long-running read > > > operating going. > > > > > > Check out this post from the Asio-users mailing > > > list: > > > > > > http://osdir.com/ml/lib.boost.asio.user/2006-11/msg00035.html > > > > > > Richard > > > > > > Cliff > > > > > > > > > _______________________________________________ > > > > Boost-users mailing list > > > > Boost-users@lists.boost.org > > > > > > > > > > http://lists.boost.org/mailman/listinfo.cgi/boost-users > > > > > > > > > _______________________________________________ > > > Boost-users mailing list > > > Boost-users@lists.boost.org > > > > > > http://lists.boost.org/mailman/listinfo.cgi/boost-users > > > > > > > > > ___________________________________________________________ > > Yahoo! Answers - Got a question? Someone out there > knows the answer. Try > > it > > now. > > http://uk.answers.yahoo.com/ > > _______________________________________________ > > Boost-users mailing list > > Boost-users@lists.boost.org > > > http://lists.boost.org/mailman/listinfo.cgi/boost-users > > > > _______________________________________________ > Boost-users mailing list > Boost-users@lists.boost.org > http://lists.boost.org/mailman/listinfo.cgi/boost-users ___________________________________________________________ Yahoo! Mail is the world's favourite email. Don't settle for less, sign up for your free account today http://uk.rd.yahoo.com/evt=44106/*http://uk.docs.yahoo.com/mail/winter07.html
participants (3)
-
Andrej van der Zee
-
Cliff Green
-
Richard Dingwall