2

When connecting to a socket with ASIO, you need to (1) create the socket; (2) open() it; (3) connect() it.

boost::asio::io_context io_context;

// (1) create socket
boost::asio::ip::tcp::socket socket(io_context);

// (2) open it
boost::system::error_code open_error;
socket.open(open_error);
if (open_error) { /* .... */ }

// (3) connect
boost::system::error_code connect_error;
boost::asio::ip::tcp::endpoint endpoint(
    boost::asio::ip::address::from_string("1.2.3.4"), 12345);
socket.connect(endpoint, connect_error);
if (connect_error) { /* .... */ }

It's pretty clear that the connect() call could fail. It's an actual networking operation, and the remote endpoint might be inaccessible, or refuse the connection, etc.

But can the open() call fail? If so, what would cause that? It doesn't seem to do much, and certainly not access the network. I think perhaps if the process is out of file descriptors then that could cause it to fail - does that seem right?

A similar question applies to sockets passed to acceptor.accept() instead of connecting outbound. More to the point it applies to the acceptor class itself: you have to open it before calling its accept() method. Can that fail?

(For both sockets and acceptors it's possible to open as part of the constructor by passing in the relevant parameters. But then the documentation says that they can throw an exception, so the same question still applies.)

Arthur Tacca
  • 8,833
  • 2
  • 31
  • 49

1 Answers1

3

The Boost.Asio docs indeed do not specify in which ways open() can fail, only that it can fail. However, it does have a table that shows which parts of the Boost.Asio low-level socket API map to which parts of the BSD socket API: for both POSIX systems and Windows systems, ip::tcp::socket::open corresponds to the socket() function, so we can assume that it can fail for at least the reasons for which socket() can fail.

In POSIX, socket() shall fail if the address family, protocol or socket type are not supported (unlikely for TCP), or if there are no file descriptors available. It may fail if you lack privileges or have run out of memory (reference). The socket() function for Windows has similar error conditions plus some Windows-specific ones (reference).

Your assumptions...

  • that this is less likely to fail than connect(), and
  • that if it does fail, the most likely cause is running out of file descriptors

...both sound reasonable to me.

The same holds for acceptor's open.

Wander Nauta
  • 18,832
  • 1
  • 45
  • 62
  • +1 I've previously answered a very similar question the same way https://stackoverflow.com/a/65811398/85371 - in case it helps people tracing these documentations themselves – sehe Jul 20 '23 at 12:09
  • Thanks, especially for the reference with the socket API mapping. – Arthur Tacca Jul 20 '23 at 21:22