From: davlet_panech (davlet_panech_at_[hidden])
Date: 2002-02-23 22:43:45
--- In boost_at_y..., "jelco78" <marcojez_at_h...> wrote:
> Only one thing: I can't understand the purpose of "Layer 2" in the
> proposed design. The library I wrote was composed of only 2 layers:
> a first, low-level, portable wrapper class set for sockets and
> addresses (which show a 100% ISO C++ interface, and a portable
> implementation), and then an higher-level stream interface (based
> a std::basic_streambuf derivation).
> So, what is the purpose and structure of "Layer 2" as described in
> the guidelines?
"Layer 2" (which talks about ~mysterious~ connector/acceptor classes)
is supposed to provide compile-time checks for the correctness of
socket operations (especially the order of calls).
Anyway, we already have a couple of socket libraries in the files
section (I suspect many of have attempted this kind of thing before --
I know I did). Perhaps it's time to consolidate our efforts and try
to come up with reasonable design. I know that David Moore has been
looking into this for a few weeks now (he has his own socket
library :) ), hopefully he can contribute here, too. Following are
my thoughts on this, as always comments are much appreciated.
- I guess we want our library to work with at least a couple of
popular protocols from the TCP/IP family. I am thinking IP proper (v4
& v6), TCP & UDP (over IPv4 & IPv6). Is that reasonable?
- I guess one important question is how to categorize different
protocols, and how to deal with their differences. I suggest as a
first step we consider all protocols to be either connection-oriented
or connectionless. This is important because the operations defined
for a connectionless socket are quite different from those of a
connected one. There are other ways to classify protocols, but I
think "connectivity" is the most important one, at least from the
application usage viewpoint.
- Based on the above classification we would have two sets of socket
1) (connection-oriented): class acceptor_socket<>, class
2) (connectionless): class bound_socket<>
All of these would be parametrized on the protocol type;
instantiation with a "wrong" protocol type (e.g.,
connected_socket<udp_ip4>) would result in a compile-time error.
- Now regarding things like protocol and address families, I think we
should leave them alone, at least for now. My understanding is that
there is a 1:1 mapping between a protocol and an address family for
most cases (including IP/TCP/UDP -- am I wrong?), so there is no need
to worry about them (we can just assume that each protocol has an
associated address type).
- Each protocol (and it's category!) would be described by a type
that will be used as the template selector for sockets. The protocol
type would be required to have certain members: `category'
(connectionless or not), `address_type', `state_type' (aka socket
descriptor). Plus, depending on category, it would also implement the
operations that make sense for that category (like connect(), accept
(), send(), etc)
Following are some examples of what I am thinking of:
// -------- Connection-oriented -----------
// An acceptor bound to a local address
acceptor_socket< tcp_ip4 > server( "localhost:80" );
// Wait for a connection
connected_socket< tcp_ip4 > client( server );
// Initiate a connection on "some_interface:80"
// to "some_host:80"
connected_socket< tcp_ip4 >
client2 ("some_interface:2000", "some_host:80" );
// Connected socket operations
// -------- Connectionless -----------
// Bind a connectionless socket to a local address
bound_socket< udp_ip4 > bsock( "localhost:1000" );
------- [END EXAMPLES] --------------------
I would like to keep the interface minimal, at least initially. I'm
determined to get the design going so I would REALLY appreciate any
suggestions you might have, especially considering that socket
libraries never seem to be quite good enough to satisfy everybody!
Boost list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk