
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 http://sourceforge.net/projects/netiphany 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 be). 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 framework. 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 kqueue.
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. Best, Don __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com