/** \mainpage The SENF Socket Library The Socket library provides a high level and object oriented abstraction of the BSD socket API. The abstraction is based on several concepts: \li The basic visible interface is a \link handle_group handle object \endlink \li The socket interface relies on a \link policy_group policy framework \endlink to configure it's functionality \li The rest of the socket API is accessible using a classic inheritance hierarchy of \link protocol_group protocol classes \endlink The handle/body architecture provides automatic reference counted management of socket instances, the policy framework provides highly efficient access to the most important socket functions (like reading and writing) and the inheritance hierarchy provides convenient access to the multitude of special and protocol dependent options. \see \ref usage \n \ref handle_group \n \ref policy_group \n \ref protocol_group \n \ref extend \n \ref implementation */ /** \page usage Using the Socket Library Whenever you use the socket library, what you will be dealing with are senf::FileHandle derived instances. The socket library relies on reference counting to automatically manage the underlying socket representation. This frees you of having to manage the socket lifetime explicitly. \section usage_create Creating a Socket Handle To create a new socket handle (opening a socket), you will need to use senf::ProtocolClientSocketHandle or senf::ProtocolServerSocketHandle. You will probably not use these templates as is but use proper typedefs (for example senf::TCPv4ClientSocketHandle or senf::PacketSocketHandle). The documentation for these socket handles are found in the protocol class (for example senf::TCPv4SocketProtocol or senf::PacketProtocol). \section usage_reusable Writing Reusable Components To make your code more flexible, you should not pass around your socket in this form. Most of your code will be using only a small subset of the senf::ProtocolClientSocketHandle or senf::ProtocolServerSocketHandle API. If instead of using the fully specified handle type you use a more incomplete type, you allow your code to be used with all socket which fulfill the minimal requirements of your code. This works, by defining a special reduced policy or handle for your code: \code typedef senf::ClientSocketHandle< senf::MakeSocketPolicy< senf::ReadablePolicy, senf::StreamFramingPolicy, senf::ConnectedCommunicationPolicy > > MyReadableHandle; \endcode This defines \c MyReadableHandle as a senf::ClientSocketHandle which will have only read functionality. Your code expects a stream interface (in contrast to a packet or datagram based interface). You will not have \c write or \c readfrom members. \c write will be disabled since the WritePolicy is unknown, \c readfrom will be disabled since a socket with the senf::ConnectedCommunicationPolicy does not have a \c readfrom member. */ /** \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 ordinary 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 typedef senf::ProtocolClientSocketHandle MyProtocolClientSocketHandle; typedef senf::ProtocolServerSocketHandle MyProtocolServerSocketHandle; \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 must not 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.
SocketHandle member Policy member
senf::ClientSocketHandle::read ReadPolicy::read (\ref senf::ReadPolicyBase)
senf::ClientSocketHandle::readfrom ReadPolicy::readfrom (\ref senf::ReadPolicyBase)
senf::ClientSocketHandle::write WritePolicy::write (\ref senf::WritePolicyBase)
senf::ClientSocketHandle::writeto WritePolicy::writeto (\ref senf::WritePolicyBase)
senf::ClientSocketHandle::connect AddressingPolicy::connect (\ref senf::AddressingPolicyBase)
senf::ClientSocketHandle::bind AddressingPolicy::bind (\ref senf::AddressingPolicyBase)
senf::ClientSocketHandle::peer AddressingPolicy::peer (\ref senf::AddressingPolicyBase)
senf::ClientSocketHandle::local AddressingPolicy::local (\ref senf::AddressingPolicyBase)
senf::ClientSocketHandle::rcvbuf BufferingPolicy::sndbuf (\ref senf::BufferingPolicyBase)
senf::ClientSocketHandle::sndbuf BufferingPolicy::rcvbuf (\ref senf::BufferingPolicyBase)
senf::ServerSocketHandle::bind AddressingPolicy::bind (\ref senf::AddressingPolicyBase)
senf::ServerSocketHandle::listen CommunicationPolicy::listen (\ref senf::CommunicationPolicyBase)
senf::ServerSocketHandle::local AddressingPolicy::local (\ref senf::AddressingPolicyBase)
senf::ServerSocketHandle::accept CommunicationPolicy::accept (\ref senf::CommunicationPolicyBase)
senf::ServerSocketHandle::acceptfrom CommunicationPolicy::accept (\ref senf::CommunicationPolicyBase)
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). \see policy_group */ /** \page implementation Implementation notes \image html SocketLibrary-classes.png */ // Local Variables: // mode: c++ // mode: flyspell // mode: auto-fill // ispell-local-dictionary: "american" // End: