2

Suppose I accept a socket by calling async_accept like this

acceptor.async_accept([](const boost::system::error_code& ec, boost::asio::ip::tcp::socket sock) 
{
if (ec) 
   return;

auto sess = std::make_shared<session>(std::move(sock));
sess->start_reading();
//...
});

My question is, in what cases can sock.is_open() return false (inside session)? I know that if, for example, I call sock.close() (or move socket object), then is_open will return false. But are there other situations in which is_open can return false? If so, under what circumstances?

For example, maybe when calling io_context::stop() or under other circumstances?

4
  • 2
    The other end of the connection could close the socket (or just drop it) at arbitrary times... Commented Oct 1 at 13:36
  • @JesperJuhl If the other side closes the connection, the session object will be destroyed because the asynchronous read operation will be canceled (start_reading). My question was in the context of session remaining active, which means this is not the case. Commented Oct 1 at 13:42
  • io_context::stop() will not do anything to individual IO objects (it would violate the thread safety guarantee, if anything) Commented Oct 1 at 13:56
  • 1
    @JesperJuhl Yes, but closing the local socket descriptor is always the responsibility of the code. An "open socket" merely retains state and prevents the descriptor from being re-used. In other words, your comment is a little misleading: in the context of this question, NO, the other end of the connection can never close the socket. (The peer can close its local socket, of course, but that's irrelevant). Commented Oct 1 at 13:59

1 Answer 1

6

The short answer is no.

That's because the post-condition of async_accept is ec.failed() || socket.open(). Of course, the socket being successfully accepted doesn't guarantee that the connection stays healthy for any duration, as is the nature of [network] connections.

Checking is_open() is rarely helpful, accept when detecting whether a socket object needs to be re-initialized (e.g. https://www.boost.org/doc/libs/latest/doc/html/boost_asio/reference/async_connect/overload1.html#boost_asio.reference.async_connect.overload1.parameters)


In wider context, a newly constructed tcp::socket may have is_open() == false, depending on the constructor arguments.

Sign up to request clarification or add additional context in comments.

4 Comments

I think you are wrong: if io_context is destroyed, then socket is closed automatically. 1) Please see this example pastebin.com/dy7tsBT4 (if you comment delete io; global_sock.is_open() will return true and false otherwise ) 2) please edit your answer
That's just something else, Joe. ::stop() is NOT destroying the context. Also, your example leverages the same shared_from_this (captured by pending completion handlers), so should be irrelevant for the exact same reasons you gave yourself
(Oh by the way, having looked at the synthetic sample, using the global_sock reference after the service lifetime has ended is Undefined Behavior; that couldn't happen with proper enable_shared_from_this in your session class)
I got your point, thank you so much!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.