Boost logo

Boost :

From: Don G (dongryphon_at_[hidden])
Date: 2005-04-24 17:22:05

Hi Boris,

> In level 0 I assume a socket to encapsulate a
> socket fd and provide methods to support the
> four mentioned I/O models. It should then be
> possible to derive another class, eg.
> ssl_socket and overwrite methods like accept()
> in order to verify the client. However I
> wonder about your ssl stream? Are you in
> level 0 or in level 1? ;)

I had assumed level 0 was sockets. No abstraction really; just
encapsulation. In my design I still need sockets :). I just don't
want them being visible beyond the level where they must be visible.
If you look at you will see
what I mean by sockets and level 0 (just my take, of course).

Where we diverge perhaps is level 1. I think the first thing that
should be done with sockets is to hide them behind a complete
abstraction. The only reason for writing code to level 0 (outside of
level 1) is for pure performance. Not that the library I am proposing
is a slouch, just that you cannot add any code or mechanism and still
be as optimal as direct sockets usage (which level 0 + inlining would

So, in my view of the world<g>, I see something like my proposal as
level 1. There should not need to be anything else at level 1. It is
a complete abstraction (or should be made so).

Back to SSL. It is an ideal example. While it uses (my definition of)
level 1 facilities, it also provides an implementation of the
abstraction defined by level 1. So it is both a producer and consumer
of level 1. I suppose you could say it is level 2, but I think it
doesn't fit there either, unless you defined level 2 to be exactly
that kind of thing only.

Beyond level 1 (and things like ssl_stream), protocol libraries and
the like would live off the level 1 abstractions or some higher level

Anyway, that is my view. :)

> I see you distinguish between read/write and
> socket! If I understand you correctly you
> don't expect any socket to provide read/write
> methods but return some kind of stream which
> is then used for reading and writing?

I am having a hard time with the limits of English (C++ is more
expressive<g>). At level 0, sockets provide send and recv as they
always have, just wrapped for safety, convenience, portable error
code returns, etc.. Which is why I cannot see how ssl_stream could
derive from the socket wrapper class. Even if these were virtual, if
the socket base class provides a get_fd() method (which I think it
must), a derived ssl_stream would violate the rule of substitution
unless you play some expensive games.

>> I'm not sure about the platform-specific
>> classes, could you clarify?
> The non-blocking/asynchronous I/O can be
> implemented in different ways. If you know
> that your target platform supports eg. kqueue
> and you have reasons to use kqueue the
> network library could offer such a platform-
> specific class to provide non-blocking/
> asynchronous I/O based on kqueue. At least
> I thought this is one goal of your library.
> However now after your question I am not
> so sure any more. ;)

I understand your point now. I was trying to satisfy the desire of
some to chose an implementation for platforms that could have
multiple choices (select + poll + kqueue). I don't think this is
something most users would ever do, but there is room for the app
developer to chose what class they instantiate for the network. I
think we would need a simple name for the common/preferred option
such as:

  network_ptr net = new network_ipv4; // default choice

  network_ptr net = new network_ipv4_kq; // not portable

Beyond this choice, the abstractions should be 100% the same to the
user and other library code.

> I see. I think I wrote in another thread that I
> view layer 0 as to be very close to the C API.
> The idea of layer 0 is (at least in my mind) that
> experienced network developers who know Berkeley
> sockets should be able to switch over very easily
> to the C++ network library - the entry level
> should be as low as possible. Your idea of level
> 0 seems to be something else?

Not at all. I just don't see encouraging anyone to work at level 0.
All higher level thinking is above that. In particular, the
abstraction I am proposing is level 1 (my definition again<g>). But,
that level 1 abstraction is ideally very much like level 0 in terms
of network semantics, just not so much like the sockets API.

> How many platforms are there without Berkeley
> sockets?

Hopefully not many, but I would put Windows in that list. :) They
have sockets, but you code with them in very non-portable ways if you
want performance. Much like the fracture between poll, epoll and

> Do we really want *not* to provide a layer close
> to Berkeley sockets because of one (?) old
> platform and make it more difficult for the the
> majority of network developers to switch over
> to the C++ network library who know and
> understand Berkeley sockets?

I would say that level 0 is a direct, perhaps even inlined wrapper
over sockets (see above). For legacy code, that would be useful. Even
for experienced developers, I believe they would be much better off
(give or take some radical optimization requirements) with the layer
I propose. If they see it otherwise, level 0 is there and is a
supported library for use by anyone.

That said, I really wanted to address the design to someone without
lots of experience in this area. There are some things that just
cannot and should not be hidden from the user (bi-directionality,
long delays, etc.), but we can make it very easy to do the simple
things (should I use gethostbyname or gethostbyname_r or
WSAAsyncGetHostByName?). And without an undue performance penalty
that would push even modest needs down a level.

Also, by using abstract interfaces, shared_ptr<> and Abstract
Factory, one can do the most amazing things with layered objects (see
posts with Peter). That was part of the goal of my design as well and
indeed part of the problem that gave it birth.


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around

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