socket representation. This frees you of having to manage the
socket lifetime explicitly.
+ \section socket_hierarchy The FileHandle hierarchy
+
+ \image html FhHierarchy.png
+
+ The senf::FileHandle class is the base of a hierarchy of socket
+ handle classes (realized as templates). These classes provide an
+ interface to the complete socket API. While going down the
+ inheritance hierarchy, the interface will be more and more
+ complete.
+
+ The most complete interface is provided by
+ senf::ProtocolClientSocketHandle and
+ senf::ProtocolServerSocketHandle. The template Arguments specifies
+ the Protocol class of the underlying socket type. These are the
+ \e only classes having public constructors and are therefore the
+ only classes, which may be created by the library user. You will
+ normally use these classes by naming a specific socket typedef
+ (e.g. senf::TCPv4ClientSocketHandle).
+
+ However, to aid writing flexible and generic code, the socket
+ library provides the senf::ClientSocketHandle and
+ senf::ServerSocketHandle class templates. These templates
+ implement a family of closely related classes based on the
+ specification of the socket policy. This policy specification may
+ be \e incomplete (see below). Instances of
+ senf::ClientSocketHandle/senf::ServerSocketHandle can be assigned
+ and converted to different ClientSocketHandle/ServerSocketHandle
+ types as long as the policy specifications are compatible.
+
\attention It is very important, to (almost) always pass the socket
handle <em>by value</em>. The socket handle is a very lightweight
class and designed to be used like an ordinary built-in type. This
is very important in combination with the policy interface.
\section policy_framework The policy framework
+
+ \image html SocketPolicy.png
The policy framework conceptually implements a list of parallel
inheritance hierarchies each covering a specific interface aspect
<dd>configures, if and how buffering is configured for a socket</dd>
</dl>
+ Every Policy value is identified by a class type. The policy types
+ themselves built an inheritance hierarchy for each policy
+ axis. For each policy axis, the root of this tree is the class
+ named '<tt>(axis name)Base</tt>' (e.g. \p FramingPolicyBase or \p
+ CommunicationPolicyBase) which is aliased to '<tt>Unspecified(axis
+ name)</tt>' (e.g. \p UnspecifiedFramingPolicy or \p
+ UnspecifiedCommunicationPolicy).
+
+ The senf::SocketPolicy template combines a set of policy classes,
+ one for each policy axis. Together, they define the behavior of a
+ socket handle. The socket handle instances do net implement any
+ socket functionality themselves, instead defering the
+ implementation to the socket classes. The interface is therefore
+ \e not implemented using virtual members, all important socket
+ functions can be inlined by the compiler to create highly
+ efficient code.
+
+ Two SocketPolicy instances are considered compatible, if all
+ policy axis are compatible. A policy axis is compatible, if one
+ policy class is either the same as the other or derived from
+ it. Two SocketHandle instances can be converted into each other,
+ as long as the SocketPolicies are compatible.
+
+ \section protocol_interface The protocol interface
+
+ \image html Protocols.png
+
+ The socket handle classes and templates only implement the most
+ important socket API methods using the policy framework. To access
+ the complete API, the protocol interface is provided. Access to
+ the protocol interface is only possible via
+ senf::ProtocolClientSocketHandle and
+ senf::ProtocolServerSocketHandle which have the necessary \c
+ protocol() member. This member returns a reference to the protocol
+ class instance which contains members covering all the API
+ function (mostly setsockopt/getsockopt related calls) not found in
+ the SocketHandle interface. The protocol interface is specific to
+ the protocol. It's implementation is quite free. The standard
+ protocols are implemented using a simple multiple-inheritance
+ hierarchy as shown above.
+
+ Since the protocol class is protocol specific (how intelligent
+ ...), the protocol class also defines the complete socket policy
+ to be used with it's protocol. Complete meaning, that every policy
+ axis must be assigned it's the most specific (that is derived)
+ policy class to be used with the protocol.
+
*/
/** \page extend Extending the Library
+
+ There are two layers, on which the socket library can be
+ extended: On the protocol layer and on the policy layer. Extending
+ the protocol layer is quite simple and works as long as the
+ desired protocol does use the same BSD API used by the standard
+ internet protocols as implemented in the standard policies
+ (i.e. it uses ordinere read() and write() or rcvfrom() or sendto()
+ calls and so on).
+
+ If however the implementation of a policy feature needs to be
+ changed, a new policy class has to be written. This also is not
+ very complicated however the integration is more complex.
+
+ \section extend_protocol Writing a new protocol class
+
+ Most protocols can be implemented by just implementing a new
+ protocol class. The protocol class must be derived from
+ senf::ConcreteSocketProtocol and takes the socket policy (as
+ created by senf::MakeSocketPolicy) as a template argument. See the
+ documentation of this class for the interface.
+
+ \attention
+ You may want to use multiple inheritance as it is used in the
+ implementation of the standard protocols (See \ref
+ protocol_interface). You must however be extra careful to ensure,
+ that every class ultimately has senf::SocketPolicy as a public
+ \e virtual base.
+
+ After the protocol class has been defined, you will probably want to
+ provide typedefs for the new protocol sockets. If the new protocol
+ is connection oriented, this will be like
+ <code>
+ typedef senf::ProtocolClientSocketHandle<MyProtocolClass> MyProtocolClientSocketHandle;
+ typedef senf::ProtocolServerSocketHandle<MyProtocolClass> MyProtocolServerSocketHandle;
+ </code>
+
+ \section extend_policy Extending the policy framework
+
+ If you have to extend the policy framework, you will need to be
+ aware of some important limitations of the socket library:
+
+ \li When you define a new policy for some axis, this new policy
+ <em>must not</em> be derived from one of the existing concrete
+ policy classes (except of course the respective policy axis
+ base class). This is important since the policy type is \e not
+ polymorphic. The policy to be used is selected by the compiler
+ using the \e static type, which is exactly what is desired,
+ since this allows calls to be efficiently inlined.
+
+ \li Therefore, extending the policy framework will make the new
+ socket probably \e incompatible with generic code which relies
+ on the policy axis which is extended. Example: If you write a
+ new write policy because your protocol does not use ordinary
+ write() system calls but some protocol specific API, Then any
+ generic function relying on senf::WritablePolicy will \e not
+ work with the new socket, since the socket does \e not have
+ this policy, it has some other kind of write policy.
+
+ Therefore you need to be careful of what you are doing. The first
+ step is to find out, which policy you will have to implement. For
+ this, find the senf::ClientSocketHandle and/or
+ senf::ServerSocketHandle members you want to change. The following
+ table shows, which policy axis is responsible for which
+ members. The policy axis base class documentation contains further
+ information on how to implement that policy.
+
+ <table class="senf">
+ <tr><th>SocketHandle member</th> <th>Policy member</th></tr>
+ <tr><td>senf::ClientSocketHandle::read</td> <td>ReadPolicy::read (\ref senf::ReadPolicyBase)</td></tr>
+ <tr><td>senf::ClientSocketHandle::readfrom</td> <td>ReadPolicy::readfrom (\ref senf::ReadPolicyBase)</td></tr>
+ <tr><td>senf::ClientSocketHandle::write</td> <td>WritePolicy::write (\ref senf::WritePolicyBase)</td></tr>
+ <tr><td>senf::ClientSocketHandle::writeto</td> <td>WritePolicy::writeto (\ref senf::WritePolicyBase)</td></tr>
+ <tr><td>senf::ClientSocketHandle::connect</td> <td>AddressingPolicy::connect (\ref senf::AddressingPolicyBase)</td></tr>
+ <tr><td>senf::ClientSocketHandle::bind</td> <td>AddressingPolicy::bind (\ref senf::AddressingPolicyBase)</td></tr>
+ <tr><td>senf::ClientSocketHandle::peer</td> <td>AddressingPolicy::peer (\ref senf::AddressingPolicyBase)</td></tr>
+ <tr><td>senf::ClientSocketHandle::local</td> <td>AddressingPolicy::local (\ref senf::AddressingPolicyBase)</td></tr>
+ <tr><td>senf::ClientSocketHandle::rcvbuf</td> <td>BufferingPolicy::sndbuf (\ref senf::BufferingPolicyBase)</td></tr>
+ <tr><td>senf::ClientSocketHandle::sndbuf</td> <td>BufferingPolicy::rcvbuf (\ref senf::BufferingPolicyBase)</td></tr>
+ <tr><td>senf::ServerSocketHandle::bind</td> <td>AddressingPolicy::bind (\ref senf::AddressingPolicyBase)</td></tr>
+ <tr><td>senf::ServerSocketHandle::listen</td> <td>CommunicationPolicy::listen (\ref senf::CommunicationPolicyBase)</td></tr>
+ <tr><td>senf::ServerSocketHandle::local</td> <td>AddressingPolicy::local (\ref senf::AddressingPolicyBase)</td></tr>
+ <tr><td>senf::ServerSocketHandle::accept</td> <td>CommunicationPolicy::accept (\ref senf::CommunicationPolicyBase)</td></tr>
+ <tr><td>senf::ServerSocketHandle::acceptfrom</td> <td>CommunicationPolicy::accept (\ref senf::CommunicationPolicyBase)</td></tr>
+ </table>
+
+ As you can see from this list, not all policy axis directly
+ contribute to the SocketHandle interface. However, some policy
+ members additionally depend on other policy axis (example:
+ AddressingPolicy::connect is only defined if the communication
+ policy is ConnectedCommunication).
*/
/** \page implementation Implementation notes
- \image html "../../SocketLibrary-classes.png" Class hierarchy
+ \image html SocketLibrary-classes.png
*/
-
\f
// Local Variables:
// mode: c++