Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

classic Classic list List threaded Threaded
37 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list
Fellow C++, Boost, and WG21 Enthusiasts, lend me your ear!

I write to inform you about exciting developments in C++ networking.

First, a bit of background. Networking comes in three flavors:

* Networking TS <https://cplusplus.github.io/networking-ts/draft.pdf>
* Boost.Asio <https://www.boost.org/doc/libs/1_69_0/doc/html/boost_asio.html>
* Standalone Asio <https://github.com/chriskohlhoff/asio>

These three are for the most part identical, except that Asio flavors
have additional features like ssl::stream and signal_set which are not
in the TS, but will very likely appear in a future update or version.
We've had Asio for over a decade now, but there is a shortage of
experts. Some people believe this shortage is because Asio in
particular (and thus, Networking TS since they have identical
interfaces) is "difficult to use." I believe it is wrong to blame Asio
for this. Concurrent programs in general are hard to write. This is
applicable:

"Unfortunately, today's reality is that only thoughtful experts can
write explicitly concurrent programs that are correct and efficient.
This is because today's programming models for concurrency are subtle,
intricate, and fraught with pitfalls that easily (and frequently)
result in unforeseen races (i.e., program corruption) deadlocks (i.e.,
program lockup) and performance cliffs (e.g., priority inversion,
convoying, and sometimes complete loss of parallelism and/or even
worse performance than a single-threaded program). And even when a
correct and efficient concurrent program is written, it takes great
care to maintain — it's usually brittle and difficult to maintain
correctly because current programming models set a very high bar of
expertise required to reason reliably about the operation of
concurrent programs, so that apparently innocuous changes to a working
concurrent program can (and commonly do, in practice) render it
entirely or intermittently nonworking in unintended and unexpected
ways. Because getting it right and keeping it right is so difficult,
at many major software companies there is a veritable priesthood of
gurus who write and maintain the core concurrent code."
   - Herb Sutter, "The Trouble with Locks",
<http://www.drdobbs.com/cpp/the-trouble-with-locks/184401930>

Although this was written in 2005 it is still relevant today. It is
understandable that Asio will be the first target of anger and
frustration when writing concurrent programs, since it is on the
"front line" so to speak. There has also been a distinct shortage of
*good* tutorials and examples for Asio. Articles or blog posts which
teach you step by step, explaining everything, and giving example code
which demonstrates best practices.

Boost.Beast is my low-level HTTP/WebSocket library which builds on Boost.Asio:
<https://github.com/boostorg/beast>

In the original release of Beast, the documentation stated "prior
understanding of Boost.Asio is required." However, field experience
has shown that users ignore that requirement and attempt to write
complex, concurrent programs as their first-time introduction to both
Beast and Asio. Based on feedback from committee members, and to serve
users better, the scope of Beast has been enlarged to include
first-time users of networking. The upcoming Boost 1.70 release
reflects this new scope and I am excited to announce some very nice
things which you can access today.

First of all, Beast documentation and examples no longer use the
"boost::asio" namespace, they the namespace alias "net::". While this
is cosmetic, it reinforces the notion when inspecting code that it is
equally applicable to Boost.Asio, Asio, and Networking TS (identifiers
which are not in the TS, such as signal_set, are still qualified with
boost::asio).

A new documentation page explains the three flavors of networking:

<https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io.html>

This is also explained in my 2018 CppCon presentation:

<https://youtu.be/7FQwAjELMek?t=444>

I have added a "Networking Refresher", a complete overview of
networking from soup to nuts. No prior knowledge or understanding of
networking is required, everything is explained in detail so if you
want to learn this is the place to start. I also kept it short, but it
is loaded with hyperlinks for further learning:

<https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io/asio_refresher.html>

There was a recent paper in Kona, P1269R0 ("Three Years with the
Networking TS")  about difficulty of implementing timeouts. To address
this, Beast now has a stream class which implements configurable
timeouts for you, and callers no longer have to fiddle with timers
manually anymore. Everything "Just Works." It achieves the P1269R0
author's goal of having timeouts "built-in to asynchronous
operations", but in a way that fits in with the design of the TS:

<https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io/timeouts.html>

I feel that this `beast::basic_stream` serves as an existence proof
that the current design of Networking TS is sound - the TS offers a
flexible toolbox which lets you build your own framework the way that
you want it, without making odd choices for you. We are still
discovering ways of leveraging it to maximum use. The
beast::websocket::stream also has built-in timeouts, but they are
enhanced to support "idle pings" (keeping client connections alive)
and everything is fully configurable:

<https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_websocket/timeouts.html>

All you need to do to get sensible, suggested websocket timeouts is
add one line of code after creating your stream:

        ws.set_option(websocket::stream_base::timeout::suggested(
beast::role_type::server));

To address the cumbersome boilerplate of writing composed operations
(specifically the need to propagate the associated allocator and
associated executor, and to avoid invoking the completion handler from
within the initiating function when the operation would complete
immediately) Beast adds two new utility base classes, with plentiful
documentation and examples throughout:

<https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io/writing_composed_operations.html>

There are two well-rounded examples which show you step by step how to
write these things in a safe way:

<https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io/writing_composed_operations/echo.html>

<https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io/writing_composed_operations/detect_ssl.html>

I have a big, new open source project which implements a server, that
uses the `system_context`, taking full advantage of native Windows and
Mac OS system-level execution context features. To support this use
case and industry feedback, the examples in Beast now default to being
always thread-safe. All examples use a "strand", and leverage P1322R0
("Networking TS enhancement to enable custom I/O executors"). Yes,
this paper which was approved in Kona, is now implemented in both
Boost.Beast, and Boost.Asio, including all of the Beast examples, so
if you pick up Boost 1.70 (or the master branches from github) you can
start playing with this as soon as you're done reading this message!!

<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1322r0.html>

We have an active #beast channel in the C++ Slack
(https://slack.cpp.al) where experienced users can help, no question
is too small! I hope you will join me and the rest of the Beast and
Asio community in exploring what the very powerful Networking TS and
Asio libraries have to offer, and build something great together!

Regards

P.S. Don't forget to star the repository! <https://github.com/boostorg/beast>
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list
Hi Vinnie,

I have followed your stuff since you were on the Juce Forum (audio
plugin developer here)

and I was wondering if you ever took a look at

https://github.com/mefyl/elle

It's a network library that use coroutine and boost asio

I was quite impressed when I saw a demo of it at a French c++ user Group.

just my 2 cents.

Le 14/03/2019 à 17:48, Vinnie Falco via Boost-users a écrit :

> Fellow C++, Boost, and WG21 Enthusiasts, lend me your ear!
>
> I write to inform you about exciting developments in C++ networking.
>
> First, a bit of background. Networking comes in three flavors:
>
> * Networking TS <https://cplusplus.github.io/networking-ts/draft.pdf>
> * Boost.Asio <https://www.boost.org/doc/libs/1_69_0/doc/html/boost_asio.html>
> * Standalone Asio <https://github.com/chriskohlhoff/asio>
>
> These three are for the most part identical, except that Asio flavors
> have additional features like ssl::stream and signal_set which are not
> in the TS, but will very likely appear in a future update or version.
> We've had Asio for over a decade now, but there is a shortage of
> experts. Some people believe this shortage is because Asio in
> particular (and thus, Networking TS since they have identical
> interfaces) is "difficult to use." I believe it is wrong to blame Asio
> for this. Concurrent programs in general are hard to write. This is
> applicable:
>
> "Unfortunately, today's reality is that only thoughtful experts can
> write explicitly concurrent programs that are correct and efficient.
> This is because today's programming models for concurrency are subtle,
> intricate, and fraught with pitfalls that easily (and frequently)
> result in unforeseen races (i.e., program corruption) deadlocks (i.e.,
> program lockup) and performance cliffs (e.g., priority inversion,
> convoying, and sometimes complete loss of parallelism and/or even
> worse performance than a single-threaded program). And even when a
> correct and efficient concurrent program is written, it takes great
> care to maintain — it's usually brittle and difficult to maintain
> correctly because current programming models set a very high bar of
> expertise required to reason reliably about the operation of
> concurrent programs, so that apparently innocuous changes to a working
> concurrent program can (and commonly do, in practice) render it
> entirely or intermittently nonworking in unintended and unexpected
> ways. Because getting it right and keeping it right is so difficult,
> at many major software companies there is a veritable priesthood of
> gurus who write and maintain the core concurrent code."
>     - Herb Sutter, "The Trouble with Locks",
> <http://www.drdobbs.com/cpp/the-trouble-with-locks/184401930>
>
> Although this was written in 2005 it is still relevant today. It is
> understandable that Asio will be the first target of anger and
> frustration when writing concurrent programs, since it is on the
> "front line" so to speak. There has also been a distinct shortage of
> *good* tutorials and examples for Asio. Articles or blog posts which
> teach you step by step, explaining everything, and giving example code
> which demonstrates best practices.
>
> Boost.Beast is my low-level HTTP/WebSocket library which builds on Boost.Asio:
> <https://github.com/boostorg/beast>
>
> In the original release of Beast, the documentation stated "prior
> understanding of Boost.Asio is required." However, field experience
> has shown that users ignore that requirement and attempt to write
> complex, concurrent programs as their first-time introduction to both
> Beast and Asio. Based on feedback from committee members, and to serve
> users better, the scope of Beast has been enlarged to include
> first-time users of networking. The upcoming Boost 1.70 release
> reflects this new scope and I am excited to announce some very nice
> things which you can access today.
>
> First of all, Beast documentation and examples no longer use the
> "boost::asio" namespace, they the namespace alias "net::". While this
> is cosmetic, it reinforces the notion when inspecting code that it is
> equally applicable to Boost.Asio, Asio, and Networking TS (identifiers
> which are not in the TS, such as signal_set, are still qualified with
> boost::asio).
>
> A new documentation page explains the three flavors of networking:
>
> <https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io.html>
>
> This is also explained in my 2018 CppCon presentation:
>
> <https://youtu.be/7FQwAjELMek?t=444>
>
> I have added a "Networking Refresher", a complete overview of
> networking from soup to nuts. No prior knowledge or understanding of
> networking is required, everything is explained in detail so if you
> want to learn this is the place to start. I also kept it short, but it
> is loaded with hyperlinks for further learning:
>
> <https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io/asio_refresher.html>
>
> There was a recent paper in Kona, P1269R0 ("Three Years with the
> Networking TS")  about difficulty of implementing timeouts. To address
> this, Beast now has a stream class which implements configurable
> timeouts for you, and callers no longer have to fiddle with timers
> manually anymore. Everything "Just Works." It achieves the P1269R0
> author's goal of having timeouts "built-in to asynchronous
> operations", but in a way that fits in with the design of the TS:
>
> <https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io/timeouts.html>
>
> I feel that this `beast::basic_stream` serves as an existence proof
> that the current design of Networking TS is sound - the TS offers a
> flexible toolbox which lets you build your own framework the way that
> you want it, without making odd choices for you. We are still
> discovering ways of leveraging it to maximum use. The
> beast::websocket::stream also has built-in timeouts, but they are
> enhanced to support "idle pings" (keeping client connections alive)
> and everything is fully configurable:
>
> <https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_websocket/timeouts.html>
>
> All you need to do to get sensible, suggested websocket timeouts is
> add one line of code after creating your stream:
>
>          ws.set_option(websocket::stream_base::timeout::suggested(
> beast::role_type::server));
>
> To address the cumbersome boilerplate of writing composed operations
> (specifically the need to propagate the associated allocator and
> associated executor, and to avoid invoking the completion handler from
> within the initiating function when the operation would complete
> immediately) Beast adds two new utility base classes, with plentiful
> documentation and examples throughout:
>
> <https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io/writing_composed_operations.html>
>
> There are two well-rounded examples which show you step by step how to
> write these things in a safe way:
>
> <https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io/writing_composed_operations/echo.html>
>
> <https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io/writing_composed_operations/detect_ssl.html>
>
> I have a big, new open source project which implements a server, that
> uses the `system_context`, taking full advantage of native Windows and
> Mac OS system-level execution context features. To support this use
> case and industry feedback, the examples in Beast now default to being
> always thread-safe. All examples use a "strand", and leverage P1322R0
> ("Networking TS enhancement to enable custom I/O executors"). Yes,
> this paper which was approved in Kona, is now implemented in both
> Boost.Beast, and Boost.Asio, including all of the Beast examples, so
> if you pick up Boost 1.70 (or the master branches from github) you can
> start playing with this as soon as you're done reading this message!!
>
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1322r0.html>
>
> We have an active #beast channel in the C++ Slack
> (https://slack.cpp.al) where experienced users can help, no question
> is too small! I hope you will join me and the rest of the Beast and
> Asio community in exploring what the very powerful Networking TS and
> Asio libraries have to offer, and build something great together!
>
> Regards
>
> P.S. Don't forget to star the repository! <https://github.com/boostorg/beast>
> _______________________________________________
> Boost-users mailing list
> [hidden email]
> https://lists.boost.org/mailman/listinfo.cgi/boost-users

--
Olivier Tristan
Research & Development
www.uvi.net

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list
In reply to this post by Boost - Users mailing list


On Thu, Mar 14, 2019 at 4:49 PM Vinnie Falco via Boost-users <[hidden email]> wrote:
Fellow C++, Boost, and WG21 Enthusiasts, lend me your ear!

I write to inform you about exciting developments in C++ networking.


There was a recent paper in Kona, P1269R0 ("Three Years with the
Networking TS")  about difficulty of implementing timeouts. To address
this, Beast now has a stream class which implements configurable
timeouts for you, and callers no longer have to fiddle with timers
manually anymore. Everything "Just Works." It achieves the P1269R0
author's goal of having timeouts "built-in to asynchronous
operations", but in a way that fits in with the design of the TS:

<https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io/timeouts.html>

I feel that this `beast::basic_stream` serves as an existence proof
that the current design of Networking TS is sound - the TS offers a
flexible toolbox which lets you build your own framework the way that
you want it, without making odd choices for you. We are still
discovering ways of leveraging it to maximum use. The
beast::websocket::stream also has built-in timeouts, but they are
enhanced to support "idle pings" (keeping client connections alive)
and everything is fully configurable:

This is excellent news. Timeouts are ASIO's biggest downfall. I'll definitely check it out.
If it's low level, and performant enough, then it paves the way for ASIO-ed connectors for things like Redis and ZeroMQ.

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list
On Thu, Mar 14, 2019 at 10:50 AM james <[hidden email]> wrote:
> This is excellent news. Timeouts are ASIO's biggest downfall. I'll definitely check it out.
> If it's low level, and performant enough, then it paves the way for ASIO-ed connectors for things like Redis and ZeroMQ.

Thanks! And we are very happy to answer questions, feel free to open
an issue or come to the #beast Slack channel.

Regards
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [boost] Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
On Fri, 15 Mar 2019 at 02:20, Vinnie Falco via Boost <[hidden email]> wrote:
Remember though I"m stuck in C++11 so no lambda capture assignment expressions.

Forever?

degski
--
"Big boys don't cry" - Eric Stewart, Graham Gouldman

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
Hi,


Am 14.03.2019 um 17:48 schrieb Vinnie Falco via Boost-users <[hidden email]<mailto:[hidden email]>>:

We've had Asio for over a decade now, but there is a shortage of
experts. Some people believe this shortage is because Asio in
particular (and thus, Networking TS since they have identical
interfaces) is "difficult to use.“

When I started using boost:asio, the biggest surprise to me was to see, that boost::asio also is a great library for synchronous networking, especially for writing programs that need to support IPv4 and IPv6 or using socket options. Almost everything is easier than directly using the plain C socket API.

The library probably was named asio, because async operations were the main improvement to the classic socket API, but that name kept me from trying it earlier. :-(

And there is one think, that IMHO should be handled in the tutorial: Lots of C programmers are familiar with using select() and lots of exciting code is structured the way to use select. Boost::asio can use null_buffers to get a similar behavior as select(): Being notified when data is ready. I know, this has a runtime performance penalty compared to using real async reading, especially on windows system, but it may it easier to convert existing code to boost::asio.

In the past days, I tried to use boost::asio::coroutine for some async operation. But that approach is hardly documented and seems to have lots of pitfalls.

I am also struggling on using synchronization primitives in async code. Unfortunately, there is no async_lock in boost::mutex and there is the requirement to call unlock() on the same thread as lock(). My synchronous code used a boost::mutex to protect against changing a std collection while iterating it to perform a possibly blocking network operation on each entry. I had to create an async version of that code and gave up after some days and simply used an additional thread.

I got all my test cases working, but I was not able to make sure, that the event handler will never block when trying to lock on the collection and I was not able to make sure that unlock() is called from the same thread, that was calling lock().

So it would be nice to find some advice or tutorial on how to use synchronization primitives (mutex, condition_variable) to synchronize async event handlers and conventional threaded code.

73, Mario
--
Mario Klebsch                     Actia I+ME GmbH
[hidden email]<mailto:[hidden email]>        Dresdenstrasse 17/18
Fon: +49 531 38 701 716           38124 Braunschweig
Fax: +49 531 38 701 88            Germany

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
On Thu, 14 Mar 2019 at 16:49, Vinnie Falco via Boost-users
<[hidden email]> wrote:
> There was a recent paper in Kona, P1269R0 ("Three Years with the
> Networking TS")  about difficulty of implementing timeouts. To address
> this, Beast now has a stream class which implements configurable
> timeouts for you, and callers no longer have to fiddle with timers
> manually anymore. Everything "Just Works." It achieves the P1269R0
> author's goal of having timeouts "built-in to asynchronous
> operations", but in a way that fits in with the design of the TS:
>
> <https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io/timeouts.html>

I have not used the synchronous API at all. But section 3.1 of P1269R0
seems to make a good point about the lack of timeouts in synchronous
calls, doesn't it?
beast::basic_stream makes using timeouts in the async API way simpler,
but is the sync API really basically unusable because of the lack of
timeouts thing?
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list


On Fri, Mar 15, 2019 at 9:45 AM Cristian Morales Vega via Boost-users <[hidden email]> wrote:
On Thu, 14 Mar 2019 at 16:49, Vinnie Falco via Boost-users
<[hidden email]> wrote:
> There was a recent paper in Kona, P1269R0 ("Three Years with the
> Networking TS")  about difficulty of implementing timeouts. To address
> this, Beast now has a stream class which implements configurable
> timeouts for you, and callers no longer have to fiddle with timers
> manually anymore. Everything "Just Works." It achieves the P1269R0
> author's goal of having timeouts "built-in to asynchronous
> operations", but in a way that fits in with the design of the TS:
>
> <https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io/timeouts.html>

I have not used the synchronous API at all. But section 3.1 of P1269R0
seems to make a good point about the lack of timeouts in synchronous
calls, doesn't it?
beast::basic_stream makes using timeouts in the async API way simpler,
but is the sync API really basically unusable because of the lack of
timeouts thing?

Yes, for anything other than a toytown application at least.

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list
In reply to this post by Boost - Users mailing list

Sigh. A few comments from real-world experience.


>  We've had Asio for over a decade now, but there is a shortage of experts. Some people believe this shortage is because Asio in

particular (and thus, Networking TS since they have identical
interfaces) is "difficult to use."
>
> 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.

In the beginning the C# program had 2 bugs (premature exit and deadlock) both of which were easy to find fix. This program has now hundreds of hours of heavy usage w/o bugs. It was easy and a joy to build thanks to the platform facilities.

In the java program I'm developing now, UI must be updated from "the UI thread". It took me whole *half an hour* to figure out how to write an executor that delegates execution to the UI thread and how to continue a completed future there (the flow is asynchronous network thread -> ui thread). All that just using the official JDK documentation, no external tutorials needed.

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


On another C++ project, I had to roll my own.. basically everything built upon thread/mutex/cv and _unfortunately_ I decided to use asio for networking and serial ports. I feel dread every time I have to visit asio code and I regret I simply didn't use native Win32 APIs with direct callbacks. There are still native bits in there because Win32 natively supports cancellation of _synchronous_ blocking operations.

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).

Asio _is_ a relatively nice wrapper around socket and serial port APIs, but that's about it, 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.

So now I'm regrettably stuck with asio for the forseeable future for two reasons: 1) laziness (i.e., writing the said socket/serial wrappers) and 2) need for timeouts and cancellation (just as well served by thread per client and CancelSynchronousIO). Lesson learned the hard way 😞

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.

-- Stian



_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list

As a followup and a concrete example, here's what C++ is competing against; this piece of C# code starts an asynchronous read of a file and waits for it to complete up to some timeout value; only platform facilities are used here (i.e., no external libraries).


How does ReadAsync complete? Executor? Thread? OS-callback? Don't know, don't care, it works. I have an idea of how to accomplish the same in C++, and it's not pleasant -- worker thread, promise/future, blocking queue and CancelSynchronousIO. Cannot even use std::async because CancelSynchronousIO needs a target thread ID.


            try {
                int bytesRead = 0;
                var operationStart = DateTime.Now;
                var vt = sourceFile.ReadAsync(writeTask.Data);
                if (vt.IsCompletedSuccessfully) {
                    bytesRead = vt.Result;
                }
                else {
                    var t = vt.AsTask();
                    if (!t.Wait(State.TransferTimeoutSeconds * 1000))
                        throw new AggregateException(new TimeoutException("Reader timed out."));
                    bytesRead = t.Result;
                }
                writeTask.Data = writeTask.Data.Slice(0, bytesRead);
                var operationDuration = (DateTime.Now - operationStart);
                volumeHealthReport.ReadStatistics.UpdateBandwidth(bytesRead, operationDuration);
                return bytesRead;
            }
            catch (AggregateException e) {
                if (e.InnerException != null) writeTask.ReaderException = e.InnerException;
                else writeTask.ReaderException = e;
                volumeHealthReport.ReadStatistics.IncrementErrorCount();
                return 0;
            }




_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
On Fri, 15 Mar 2019 at 14:44, Vinnie Falco via Boost-users
<[hidden email]> wrote:
> 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.

How much time I did lose looking at "services" when I actually only
needed a "composed operation"... (at that point the ASIO docs had one
example of a service, but none of a "composed operation"; now it has
of both, so it's improving).


> If you define
>
> struct sync_socket
> {
>   net::io_context ioc_;
>   net::ip::tcp::socket_;
>   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>
> std::size_t
> sync_socket::
> write_some (Buffers const& b, error_code& ec)
> {
>   std::size_t n;
>   timer_.expires_after(seconds(30));
>   timer_.async_wait(
>     [&](error_code ec)
>     {
>       socket_.cancel(ec):
>     });
>   socket_.async_write_some(b,
>     [&](error_code ec_, std::size_t n_)
>     {
>       ec = ec_; n = n_;
>     });
>     ioc_.run();
>     return n;
> }
>
> Now, you can use `sync_socket` with all the usual sync write operations like `net::write`, and get timeouts.

When you explain it it actually sounds obvious... and I feel silly for
not seeing it. You do that a lot to me.
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list
In reply to this post by Boost - Users mailing list

> I see now...your ideas on how to implement it in C++

convince me more than anything that the documentation is the problem.

The documentation definitely is a problem, but consider the following trade-offs:

- It took me half an hour to write the function in C# based on simple platform-provided and easily discoverable abstractions (IntelliSense lists ReadAsync just by side with Read; from there on it's easy to discover the remaining bits and pieces, and there's not much more to understand for the simplest use cases like that one).

- It'd probably take me 2-3 hours to implement the said thread/queue algorithm. It'd be boring, "obviously correct" code, built on simple concurrency primitives, understandable and maintainable by others. It'd also have simple failure modes.

- It'd take me ?? hours to understand the myriad of underlying asio concepts and their interplay, ?? hours to implement it, ?? hours to test it suitably (or become convinced of correctness in another way) and it'd have more complex failure modes (as anything else asynchronous). Also it would probably be non-understandable "black magic" to others who haven't spent at least ?? hours understanding the same bits of asio as well.

I have taken a look at your tutorial on writing composed operations -- which is very well written -- but I already see that the time required to read and understand it is longer than the time I used to implement the pasted C# snippet. (Yes, it demonstrates a different use-case, but the point stands I believe.)

I'm not disputing that asio is built on solid abstractions and concepts, what I'm trying to say is that "something" should exist that would allow me to write the same functionality in 30 minutes in C++ the only prior knowledge being "there exists primitive for asynchronously reading from a file" (the same prior knowledge in the case of C#).

Whether that "something" is "documentation for dummies", a "book of recipes", high-level utility library, … ?, I do not know.

I only know that I'm 2-3X more productive in Java/C# than in C++ (collusion of different factors; another story), and the gap is increasing. Working code needs to be delivered, customers are waiting and there's only so much time one can dedicate to studying arcane details of solidly designed but on the first sight impenetrable libraries.

-- Stian


From: Vinnie Falco <[hidden email]>
Sent: Friday, March 15, 2019 3:46:07 PM
To: Stian Zeljko Vrba
Cc: [hidden email] List; [hidden email]
Subject: Re: [Boost-users] Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!
 
On Fri, Mar 15, 2019 at 7:38 AM Stian Zeljko Vrba <[hidden email]> wrote:
> I have an idea of how to accomplish the same in C++, and
> it's not pleasant -- worker thread, promise/future, blocking
> queue and CancelSynchronousIO. Cannot even use
> std::async because CancelSynchronousIO needs a
> target thread ID.

Yes, yes! I see now...your ideas on how to implement it in C++
convince me more than anything that the documentation is the problem.
There's no need for any of that stuff, the code you provided could be
implemented in C++ using asio without too much fuss, and there are
actually several ways to do it all of which are succinct and will work
wonderfully.

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list
I think you largely underestimate how many (often conflicting) requirements and user expectations a high-quality C++ library has to deal with. While efficiency in the C# world is no doubt important, it's worth remembering that a high-quality C++ library needs to be precisely specified and be very specific with its requirements and guarantees. This is why there's so many concepts required to grasp - ASIO has to introduce the necessary vocabulary to be able to provide an exact specification. Few, if any, C# programmers need to worry where a library gets their memory from or whether said library has customization points that allow the user to plug any homegrown async model they use in their project into the library (which is why ASIO has `async_result` and allows you to customize memory allocations via allocators where applicable). Additionally, judging by the API you mention, few C# users have a need to do efficient scatter-gather using non-contigous buffers. Remember, C++ is often used where no other high-level language has gone before.

I could go on and put features from both ASIO and the C# async library side-by-side, but I think you get the picture. C++ libraries aren't complex because library developers like to masturbate while watching listings of their code - the complexity is there for a purpose (of course, sometimes it's not justifiable, mistakes happen). Library authors in higher-level languages can often make a lot of arbitrary decisions in a library, likely, because their users don't mind for the most part. In C++, a component that makes arbitrary decisions without any way to change them or to customize, most likely doesn't get used (anyone remember std::async() ?).

On Fri, Mar 15, 2019 at 4:50 PM Stian Zeljko Vrba via Boost-users <[hidden email]> wrote:

> I see now...your ideas on how to implement it in C++

convince me more than anything that the documentation is the problem.

The documentation definitely is a problem, but consider the following trade-offs:

- It took me half an hour to write the function in C# based on simple platform-provided and easily discoverable abstractions (IntelliSense lists ReadAsync just by side with Read; from there on it's easy to discover the remaining bits and pieces, and there's not much more to understand for the simplest use cases like that one).

- It'd probably take me 2-3 hours to implement the said thread/queue algorithm. It'd be boring, "obviously correct" code, built on simple concurrency primitives, understandable and maintainable by others. It'd also have simple failure modes.

- It'd take me ?? hours to understand the myriad of underlying asio concepts and their interplay, ?? hours to implement it, ?? hours to test it suitably (or become convinced of correctness in another way) and it'd have more complex failure modes (as anything else asynchronous). Also it would probably be non-understandable "black magic" to others who haven't spent at least ?? hours understanding the same bits of asio as well.

I have taken a look at your tutorial on writing composed operations -- which is very well written -- but I already see that the time required to read and understand it is longer than the time I used to implement the pasted C# snippet. (Yes, it demonstrates a different use-case, but the point stands I believe.)

I'm not disputing that asio is built on solid abstractions and concepts, what I'm trying to say is that "something" should exist that would allow me to write the same functionality in 30 minutes in C++ the only prior knowledge being "there exists primitive for asynchronously reading from a file" (the same prior knowledge in the case of C#).

Whether that "something" is "documentation for dummies", a "book of recipes", high-level utility library, … ?, I do not know.

I only know that I'm 2-3X more productive in Java/C# than in C++ (collusion of different factors; another story), and the gap is increasing. Working code needs to be delivered, customers are waiting and there's only so much time one can dedicate to studying arcane details of solidly designed but on the first sight impenetrable libraries.

-- Stian


From: Vinnie Falco <[hidden email]>
Sent: Friday, March 15, 2019 3:46:07 PM
To: Stian Zeljko Vrba
Cc: [hidden email] List; [hidden email]
Subject: Re: [Boost-users] Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!
 
On Fri, Mar 15, 2019 at 7:38 AM Stian Zeljko Vrba <[hidden email]> wrote:
> I have an idea of how to accomplish the same in C++, and
> it's not pleasant -- worker thread, promise/future, blocking
> queue and CancelSynchronousIO. Cannot even use
> std::async because CancelSynchronousIO needs a
> target thread ID.

Yes, yes! I see now...your ideas on how to implement it in C++
convince me more than anything that the documentation is the problem.
There's no need for any of that stuff, the code you provided could be
implemented in C++ using asio without too much fuss, and there are
actually several ways to do it all of which are succinct and will work
wonderfully.
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list

Remember, C++ is often used where no other high-level language has gone before. 


I'm well aware of that. However, how is that an argument for also not providing user-friendly, "instant productivity" high-level wrappers? By not doing that, developers having simple needs with reasonable [1] defaults are doomed to chase the rabbit-hole of complex specifications and reinvent the wheel again and again. Countless hours of programmer productivity wasted.


[1] Yes, what is reasonable? Look towards C# or Java. The wheel has already been invented.


Also, when it's easier (at least to me) to grasp raw Win32/Linux APIs than to study asio concepts and how they fit together, then the whole purpose of the standard library is defeated. Because: given an option of A: use time to learn concepts valid in C++ world only; option B: use (less) time to learn and use general OS mechanisms and concepts.. I know which route I'm going to choose and which route gives more long-term and more reusable knowledge. And probably a faster way towards working code, which is what matters in the end.


-- Stian


From: Damian Jarek <[hidden email]>
Sent: Friday, March 15, 2019 7:08:32 PM
To: [hidden email]
Cc: Vinnie Falco; Stian Zeljko Vrba
Subject: Re: [Boost-users] Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!
 
I think you largely underestimate how many (often conflicting) requirements and user expectations a high-quality C++ library has to deal with. While efficiency in the C# world is no doubt important, it's worth remembering that a high-quality C++ library needs to be precisely specified and be very specific with its requirements and guarantees. This is why there's so many concepts required to grasp - ASIO has to introduce the necessary vocabulary to be able to provide an exact specification. Few, if any, C# programmers need to worry where a library gets their memory from or whether said library has customization points that allow the user to plug any homegrown async model they use in their project into the library (which is why ASIO has `async_result` and allows you to customize memory allocations via allocators where applicable). Additionally, judging by the API you mention, few C# users have a need to do efficient scatter-gather using non-contigous buffers. Remember, C++ is often used where no other high-level language has gone before.

I could go on and put features from both ASIO and the C# async library side-by-side, but I think you get the picture. C++ libraries aren't complex because library developers like to masturbate while watching listings of their code - the complexity is there for a purpose (of course, sometimes it's not justifiable, mistakes happen). Library authors in higher-level languages can often make a lot of arbitrary decisions in a library, likely, because their users don't mind for the most part. In C++, a component that makes arbitrary decisions without any way to change them or to customize, most likely doesn't get used (anyone remember std::async() ?).

On Fri, Mar 15, 2019 at 4:50 PM Stian Zeljko Vrba via Boost-users <[hidden email]> wrote:

> I see now...your ideas on how to implement it in C++

convince me more than anything that the documentation is the problem.

The documentation definitely is a problem, but consider the following trade-offs:

- It took me half an hour to write the function in C# based on simple platform-provided and easily discoverable abstractions (IntelliSense lists ReadAsync just by side with Read; from there on it's easy to discover the remaining bits and pieces, and there's not much more to understand for the simplest use cases like that one).

- It'd probably take me 2-3 hours to implement the said thread/queue algorithm. It'd be boring, "obviously correct" code, built on simple concurrency primitives, understandable and maintainable by others. It'd also have simple failure modes.

- It'd take me ?? hours to understand the myriad of underlying asio concepts and their interplay, ?? hours to implement it, ?? hours to test it suitably (or become convinced of correctness in another way) and it'd have more complex failure modes (as anything else asynchronous). Also it would probably be non-understandable "black magic" to others who haven't spent at least ?? hours understanding the same bits of asio as well.

I have taken a look at your tutorial on writing composed operations -- which is very well written -- but I already see that the time required to read and understand it is longer than the time I used to implement the pasted C# snippet. (Yes, it demonstrates a different use-case, but the point stands I believe.)

I'm not disputing that asio is built on solid abstractions and concepts, what I'm trying to say is that "something" should exist that would allow me to write the same functionality in 30 minutes in C++ the only prior knowledge being "there exists primitive for asynchronously reading from a file" (the same prior knowledge in the case of C#).

Whether that "something" is "documentation for dummies", a "book of recipes", high-level utility library, … ?, I do not know.

I only know that I'm 2-3X more productive in Java/C# than in C++ (collusion of different factors; another story), and the gap is increasing. Working code needs to be delivered, customers are waiting and there's only so much time one can dedicate to studying arcane details of solidly designed but on the first sight impenetrable libraries.

-- Stian


From: Vinnie Falco <[hidden email]>
Sent: Friday, March 15, 2019 3:46:07 PM
To: Stian Zeljko Vrba
Cc: [hidden email] List; [hidden email]
Subject: Re: [Boost-users] Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!
 
On Fri, Mar 15, 2019 at 7:38 AM Stian Zeljko Vrba <[hidden email]> wrote:
> I have an idea of how to accomplish the same in C++, and
> it's not pleasant -- worker thread, promise/future, blocking
> queue and CancelSynchronousIO. Cannot even use
> std::async because CancelSynchronousIO needs a
> target thread ID.

Yes, yes! I see now...your ideas on how to implement it in C++
convince me more than anything that the documentation is the problem.
There's no need for any of that stuff, the code you provided could be
implemented in C++ using asio without too much fuss, and there are
actually several ways to do it all of which are succinct and will work
wonderfully.
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list
On Fri, Mar 15, 2019 at 11:58 AM Stian Zeljko Vrba <[hidden email]> wrote:
>  However, how is that an argument for also not providing user-friendly,
> "instant productivity" high-level wrappers? By not doing that, developers
> having simple needs with reasonable [1] defaults are doomed to chase
> the rabbit-hole of complex specifications and reinvent the wheel again
> and again. Countless hours of programmer productivity wasted.

So your complaint is not that Asio is bad, but that the author stopped
when he should have kept going and writing more code? Nothing stops
you or anyone else from supplying that missing code. As I have done
with Beast.
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list
>>  However, how is that an argument for also not providing user-friendly,
>> "instant productivity" high-level wrappers? By not doing that, developers
>> having simple needs with reasonable [1] defaults are doomed to chase
>> the rabbit-hole of complex specifications and reinvent the wheel again
>> and again. Countless hours of programmer productivity wasted.
>
> So your complaint is not that Asio is bad, but that the author stopped
> when he should have kept going and writing more code? Nothing stops
> you or anyone else from supplying that missing code. As I have done
> with Beast.

That's not how I read the OP's point. He seemed to me to be pointing out
that .NET APIs provide a stupid-simple API on top of lots of complexity
which itself sits on top of the Win32 winsock API.

And that I find a very fair criticism of the Networking TS, and one
shared by a ton of people on WG21. Networking ought to be some
stupid-simple coroutinised Ranges i/o API on the top. Then stuff like
strands, i/o contexts, completion tokens et al in a distinct, held
separate, API layer that you never see from the stupid simple API layer,
unless you ask. And then very low level almost-raw-sockets in a third,
distinct, held separate API at the bottom, that you ought to never see
unless you really have to.

That's the ideal in a lot of people's opinion, but nobody has the time
to do it right. So we standardise what's common practice, not what
people would prefer common practice ought to be. And that's entirely
right and proper in my book. Standards ought to be about existing
practice not about innovation, and this is one reason I find the current
trajectory of one half of the Networking TS into pure innovation land
(i.e. Executors, which don't exist anywhere yet in the proposed form)
worrying.

Me personally, I'd really like to see the bottom level part of
Networking minus all the concurrency stuff standardised separately as
soon as possible. We understand that part well. But, up to the TS
editors and champions in the end, and they've not decided to do that.

Niall
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list
On Fri, Mar 15, 2019 at 12:19 PM Niall Douglas via Boost-users
<[hidden email]> wrote:
> That's not how I read the OP's point. He seemed to me to be pointing out
> that .NET APIs provide a stupid-simple API on top of lots of complexity
> which itself sits on top of the Win32 winsock API.

Well, I think you read it incorrectly.

> And that I find a very fair criticism of the Networking TS

You're doing the same thing that the OP did, which is blaming
Networking TS for not doing enough. Let me see if I can explain it
"stupid-simple" for you:

We have this lower layer N (which is Networking TS) but users want SS
(stupid-simple high level interface). SS can be implemented in terms
of N, and you criticize Networking TS because it is N and not SS. It
sounds like I have perfectly characterized the point of both the OP
and yourself. I agree that we need SS but that doesn't mean we should
not have N. Then there's B (for Beast) which uses N, and can be used
to write SS but that's a whole different discussion :)

Here's a diagram to make it easy:

SS  Stupid/Simple        <--- You want this
B    Beast                     <--- We have this now
N    Networking TS       <-- We've had this

Please show me on the diagram why the availability of N and/or B are
obstacles to implement SS?

Thanks
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list
>> And that I find a very fair criticism of the Networking TS
>
> You're doing the same thing that the OP did, which is blaming
> Networking TS for not doing enough.

That would be a mischaracterisation. What I said is that there is an
ideal design which lots of people would like if infinite development
resources were available. The kind of resourcing which .NET had, for
example. But we don't and didn't have that, so we don't get the
stupid-simple API part. We stop short in the complex intermediate API,
with the layers all smooshed together and indistinct. And not separated
cleanly.

> Please show me on the diagram why the availability of N and/or B are
> obstacles to implement SS?

Beast is an extreme example of a design wholly dependent on that of an
external library. As ASIO changes, you'll have to spent a lot of time
keeping up using resources which you'd prefer to invest elsewhere. This
is a big reason why people don't choose Boost, and instead do poor man's
local clones of Boost facilities. It guarantees no coupling on
externally moving targets.

For the same reason, it takes a lot of resources to build stupid simple
high level APIs on top of shifting lower level APIs. I'm not sure it can
be done by people unless full time employed to do so. And that's been
historically very hard in C++, only a very few parts of the standard
library were developed by people employed to solely do that and nothing
else.

So tldr, it's not an engineering problem, it's a resourcing problem,
including the enormous resourcing requirement to build a consensus at
WG21 and get it through plenary. Look at the vast resourcing Ranges or
Coroutines sucked down, for example. High level stupid simple APIs are
hideously expensive to standardise, even for a big multinational
corporation like Microsoft (which largely sponsored both).

Niall
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
On Fri, Mar 15, 2019 at 8:19 PM Niall Douglas via Boost-users
<[hidden email]> wrote:
>
> Me personally, I'd really like to see the bottom level part of
> Networking minus all the concurrency stuff standardised separately as
> soon as possible. We understand that part well. But, up to the TS
> editors and champions in the end, and they've not decided to do that.

I think a lot of people, myself included, would have been happy with
just having access to a low-level standard sockets API; and then building on top
of it later on.

Cheers,
Miguel
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!

Boost - Users mailing list
In reply to this post by Boost - Users mailing list

> Nothing stops you or anyone else from supplying that missing code. 


?! As I explained in the previous mail, (lack of) TIME stops me. I'm an "ordinary programmer" who *needs* networking/serial/async, but I don't need ridiculously high performance, am not networking expert and have no desire to become one. I have even less desire to spend 5X or more time developing software that will have unnecessarily high performance (!) compared to 1X development effort for "satisfactory performance" (i.e., "it works for the use case"). And I believe that I'm not alone there.


> That's not how I read the OP's point. He seemed to me to be pointing out that .NET APIs provide a stupid-simple API on top of lots of complexity which itself sits on top of the Win32 winsock API.


That's the correct interpretation.


> Networking ought to be some stupid-simple coroutinised Ranges i/o API on the top. […]


This.


-- Stian



_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
12