Boost logo

Boost :

Subject: Re: [boost] [Boost-users] Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!
From: Vinnie Falco (vinnie.falco_at_[hidden])
Date: 2019-03-15 14:43:03

On Fri, Mar 15, 2019 at 7:19 AM Stian Zeljko Vrba <vrba_at_[hidden]> wrote:

> > I believe it is wrong to blame Asio for this.
> I disagree. Recently, I've been coding parallel, including networked &
> asynchronous, programs in C# and Java, and the experience has been a JOY. You
> get threads, executors, synchronization primitives, tasks, cancellation,
> monadic futures and concurrent (blocking and non-blocking) data structures
> out of the box with the platform, plus a myriad of extensions as libraries.
> As for executors, you don't need to be bothered with them unless you really
> want to for some reason.

If you were to compare POSIX or BSD sockets to C# and Java, you would say
exactly the same things. Asio (like Beast) is a low-level, portable
abstraction of I/O. You can BUILD "threads", "executors", "synchronization
primitives", "tasks", "cancellation", "monadic futures", and "concurrent
data structures" with it. Does this mean OS-level sockets are the wrong

Of course not. The reason C# seems "ahead" of C++ is two-fold:

1. WG21 goofed up by delaying networking
2. C# is not developed through the International Standards Process

These mistakes are being fixed though, and you will see library support in
C++ catch up by leaps and bounds. And when we finally get these things
(built on top of Asio/Networking TS, which has proven over and over to be
the correct low-level abstraction) it will be better than C#, Java, or Rust.

Compare the documentation for Vertx ( or netty (both Java toolkits
> for writing asynchronous reactive programs) with that of asio.

Yes I agree, there is a lack of documentation and especially tutorials for
beginners (which I am trying to fix). This has nothing to do with whether
Asio is the right portable, low-level abstraction (it is) but the lack of
guidance from the author could lead you to believe incorrect things about
the lib.

Once I attempted to write an asio service, tried to understand the simple
> example from the documentation, and I gave up. I used a thread, blocking
> call and CancelSynchronousIO (and I consider myself fortunate to develop
> for Windows only that has it).

The documentation on services is particularly scant. There is no
explanation of what they are for, how to use them, best practices, or even
"Frequently Asked Questions." I was able to figure it out though, but I am
able to focus all of my time on it.

> Asio _is_ a relatively nice wrapper around socket and serial port APIs,
> but that's about it

Yes now you're getting close to an accurate description. More correct would
be to say that Asio provides robust abstractions of buffers, dynamic
buffers, synchronous I/O, and asynchronous I/O. Networking is a subset of
that (but not the only part, see signals and serial ports, and soon file

> IMO. On the other hand, I could have written the same wrappers around
> native APIs in two days and not haul along what I consider the baggage of
> technical debt that is asio in the codebase.

There is no API technical debt. That is to say, that the interfaces are
modern and up-to-date. You could argue that particular implementations such
as Boost.Asio have extra code to provide C++03 compatibility, but this has
nothing to do with the soundness of the design. As these interfaces are
part of a TS, there will be implementations in gcc and clang appearing
shortly (if not already so). These will be written from scratch so there
will be no support for older C++.

> Conclusion, if any: many people just want/need thread per client and
> synchronous IO for simplicity, but until asio/networking TS provide for
> timeouts and cancellation of synchronous requests, it's a wrong tool for
> those people, me included.

If you define

struct sync_socket
  net::io_context ioc_;
  net::steady_timer timer_;
  template<class Buffers>
  std::size_t write_some (Buffers const& b);

You can easily implement timeouts in `write_some` thusly:

template<class Buffers>
write_some (Buffers const& b, error_code& ec)
  std::size_t n;
    [&](error_code ec)
    [&](error_code ec_, std::size_t n_)
      ec = ec_; n = n_;
    return n;

Now, you can use `sync_socket` with all the usual sync write operations
like `net::write`, and get timeouts.


Boost list run by bdawes at, gregod at, cpdaniel at, john at