How to check if socket is closed in Boost.Asio?
Asked Answered
G

6

9

What is the easiest way to check if a socket was closed on the remote side of the connection? socket::is_open() returns true even if it is closed on the remote side (I'm using boost::asio::ip::tcp::socket).

I could try to read from the stream and see if it succeeds, but I'd have to change the logic of my program to make it work this way (I do not want data to be extracted from the stream at the point of the check).

Gilliette answered 4/5, 2009 at 3:5 Comment(5)
Why do you need to know if the remote connection has closed?Impenetrability
Also, are you using an application protocol of your own design or a standard protocol?Impenetrability
I'm writing a basic chat program, and I need to notify the user that the other person closed the app. I have my own protocol, and I've already added a "Quit" message. The only drawback is that it isn't sent if the app is killed/crashes/etc.Gilliette
Your question is ill-formed. What you're asking for is a way to detect if the connection was closed by the peer.Demarcusdemaria
Maybe you can perform an asynchronous or synchronous read with a boost::asio::null_buffers instance as buffer argument?Ensnare
W
7

If the connection has been cleanly closed by the peer you should get an EOF while reading. Otherwise I generally ping in order to figure out if the connection is really alive.

Weslee answered 4/5, 2009 at 10:1 Comment(1)
...and I need to read to get the EOF. I guess there's no way around then. Thanks!Gilliette
S
14

Just check for boost::asio::error::eof error in your async_receive handler. It means the connection has been closed. That's the only proper way to do this.

Satan answered 18/9, 2012 at 23:9 Comment(0)
E
8

Is there a boost peek function available? Most socket implementations have a way to read data without removing it from the queue, so you can read it again later. This would seem to satisfy your requirements.

After quickly glancing through the asio docs, I wasn't able to find exactly what I was expecting, but that doesn't mean its not there.

I'd suggest this for starters.

Eastbourne answered 4/5, 2009 at 13:26 Comment(3)
Yes, you're right. You can pass a flag to the "receive" method that tells it not remove the data. I was using the "read_some" method, which doesn't have this flag argument. Thanks for pointing it out!Gilliette
suppose you have setup the socket and response then you can setup a stream e.g. std::istream myhttpstream(&presponse); and then you can use the std::istream::peek() function .Ddene
I do this: received = socket().receive(boost::asio::buffer(buf), tcp::socket::message_peek);Gaziantep
W
7

If the connection has been cleanly closed by the peer you should get an EOF while reading. Otherwise I generally ping in order to figure out if the connection is really alive.

Weslee answered 4/5, 2009 at 10:1 Comment(1)
...and I need to read to get the EOF. I guess there's no way around then. Thanks!Gilliette
D
2

I think that in general once you open a socket, you should start reading it inmediately and never stop doing so. This way you can make your server or client to support both synchronous and asynchronous protocols. The moment the client closes the connection, the moment the read will tell you this.

Dobbin answered 9/5, 2009 at 23:6 Comment(1)
I can't see there is any relation between "start reading it inmediately and never stop doing so" and "making your server or client to support both synchronous and asynchronous protocols". Could you please explain that in more detail for me?Ewart
O
0

Using error_code is able to check the condition whether the client is connected or not. If the connection is success, the error_code error.value() will return 0, else return other value. You can also check the message() from the error_code.

Orabelle answered 24/5, 2009 at 12:3 Comment(0)
W
0
boost::asio::socket_base::keep_alive keepAlive(true);
peerSocket->set_option(keepAlive);

Enable keep alive for the peer socket. Use the native socket to adjust the keepalive interval so that as soon as the connection is closed the async_receive handler will get EOF while reading.

Configuring TCP keep_alive with boost::asio

Weaponry answered 1/4, 2020 at 18:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.