X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Socket%2FSocketProtocol.hh;h=b41fccb8b05e182579462235abe3db3a3e5f30d0;hb=3863d46dd898b7bc35ea8c6ccd8563b18762a6b6;hp=4dbd95bd41361d989748cebb29f45eabfb354317;hpb=c52cd7d87dbb525c1267aad27391b8b7365dbb57;p=senf.git diff --git a/Socket/SocketProtocol.hh b/Socket/SocketProtocol.hh index 4dbd95b..b41fccb 100644 --- a/Socket/SocketProtocol.hh +++ b/Socket/SocketProtocol.hh @@ -1,9 +1,9 @@ // $Id$ // -// Copyright (C) 2006 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) -// Stefan Bund +// Copyright (C) 2006 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -20,23 +20,103 @@ // Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef HH_SocketProtocol_ -#define HH_SocketProtocol_ 1 +/** \file + \brief SocketProtocol and ConcreteSocketProtocol public header + */ + +// The private inheritance idea should indeed work very well: We just need to change the +// implementations of body() and protocol() and that of the ProtocolClient/ServerSocketHandle +// constructors and the SocketBody constructor. The body and the protocol would still be visible +// like several instances because of the private inheritance but we would save the backwards +// pointer. + +/** \defgroup protocol_group The Protocol Classes + +
+ \ref SocketProtocol + \ref UNSocketProtocol + \ref PacketSocketProtocol + \ref ConcreteSocketProtocol + \ref BSDSocketProtocol + \ref DatagramSocketProtocol + \ref TCPSocketProtocol + \ref UNDatagramSocketProtocol + \ref AddressableBSDSocketProtocol + \ref TCPv4SocketProtocol +
+ \htmlonly Protocols \endhtmlonly + + 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 + functions (mostly setsockopt/getsockopt related calls but there may be more, this is completely + up to the implementor of the protocol class) 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 \e 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 and that no policy axis is allowed to be left unspecified. + + \see + \ref handle_group \n + \ref policy_group + */ + +/** \defgroup concrete_protocol_group Protocol Implementations (Concrete Protocol Classes) + \ingroup protocol_group + + Theese protocol classes define concrete and complete protocol implementations. They inherit from + ConcreteSocketProtocol and are used with the ProtocolClientSocketHandle and + ProtocolServerSocketHandle templates to instantiate socket handles. Appropriate typedefs are + always provided. + + Every protocol defines both the protocol and the policy interface provided by that protocol. See + the documentation of the protocol classes listed below for more information on the supported + protocols. Every protocol class documents it's policy interface. Use the 'list all members' link + of the protocol class to find the complete policy interface. + */ + +/** \defgroup protocol_facets_group Protocol Facets + \ingroup protocol_group + + The protocol facets are classes used as building blocks to build concrete protocol classes. Each + protocol facet will implement some functional part of the protocol interface. The protocol + facets all inherit from SocketProtocol by public \e virtual inheritance. This ensures the + accessibility of the socket body from all facets. + */ + +#ifndef HH_SENF_Socket_SocketProtocol_ +#define HH_SENF_Socket_SocketProtocol_ 1 // Custom includes #include -// TODO: this is really bad. This includes and predefs should be restructured +// Hrmpf ... I have tried very hard, but I just can't find a nice, generic way to clean +// up this include #include "SocketHandle.ih" //#include "SocketProtocol.mpp" ///////////////////////////////hh.p//////////////////////////////////////// -namespace satcom { -namespace lib { +namespace senf { + + /// \addtogroup protocol_group + /// @{ class SocketPolicyBase; - class SocketProtocol : boost::noncopyable + /** \brief Socket Protocol base class + + This is the base class of all socket protocol classes. Every protocol class must directly or + indirectly inherit from SocketProtocol + + \attention SocketProtocol must \e always be inherited using public \e virtual inheritance. + */ + class SocketProtocol + : boost::noncopyable { public: /////////////////////////////////////////////////////////////////////////// @@ -56,26 +136,142 @@ namespace lib { ///@} /////////////////////////////////////////////////////////////////////////// - SocketBody & body() const; virtual SocketPolicyBase const & policy() const = 0; - + ///< Access the policy instance + /////////////////////////////////////////////////////////////////////////// // Virtual interface - virtual std::auto_ptr clone() const = 0; virtual unsigned available() const = 0; - virtual bool eof() const = 0; + ///< Return (maximum) number of bytes available for reading + ///< without < blocking + /**< This member will check in a (very, sigh) protocol + dependent way, how many bytes may be read from a socket + in a single (non-blocking) read operation. If the + socket does not support reading (viz. NotReadablePolicy + is set), this member should always return \c 0. + + Depending on the protocol, it may not be possible to + return a good value. In this case, an upper bound may + be returned (e.g.: When reading from a socket which + returns ethernet frames, returning 1500 from + available() is ok). However, this should only be done + as a last resort. Also beware, that this number should + not be too large since the socket layer will always + need to allocate that number of bytes for the data to + be read. */ + + virtual bool eof() const = 0; ///< Check for end-of-file condition + /**< This is another check which (like available()) is + extremely protocol dependent. This member will return + \c true only, if at end-of-file. If the protocol does + not support the notion of EOF, this member should + always return \c false. */ + + virtual void close(); ///< Close socket + /**< This override will automatically \c shutdown() the + socket whenever it is closed. + \throws senf::SystemException + \fixme Move into (at least) BSDSOcketProtocol */ + + virtual void terminate() const; ///< Forcibly close socket + /**< This override will automatically \c shutdown() the + socket whenever it is called. Additionally it will + disable SO_LINGER to ensure, that v_terminate will not + block. Like the overriden method, this member will ignore + failures and will never throw. It is therefore safe to be + called from a destructor. + \fixme Move into (at least) BSDSocketProtocol */ + virtual void state(SocketStateMap & map, unsigned lod) const; + ///< Return socket state information + /**< This member is called to add state information to the + status \a map. The protocol map should provide as + detailed information as possible. The amount of + information to be added to the map is selected by the + \a lod value with a default value of 0. The + interpretation of the \a lod value is completely + implementation defined. + + Every class derived from SocketProtocol should + reimplement state(). The reimplemented method should + call (all) baseclass-implementations of this + member. + + The \a map Argument is a map which associates + std:string keys with std:string-like values. The map + keys are interpreted as hierarchical strings with '.' + as a separator (like hostnames or struct or class + members). They are automatically sorted correctly. + + The values are std:string with one additional feature: + they allow assignment or conversion from *any* type as + long as that type is streamable. This simplifies + assigning non-string values to the map: + + \code + map["socket.protocol.ip.address"] << peer(); + map["socket.protocol.tcp.backlog"] << backlog(); + \endcode + + This will work even if peer() returns an ip-address + object or backlog() returns an integer. The values are + automatically converted to their string representation. + + Additionally, if the slot the date is written to is not + empty, the \<\< operator will add add a comma + as separator. */ protected: + FileHandle fh() const; ///< Get a FileHandle for this instance + /**< This member will re turn a FileHandle instance for this + protocol instance. You may cast this FileHandle + instance to a ClientSocketHandle / ServerSocketHandle + as long as you know some of the socket policy using + static_socket_cast or dynamic_socket_cast */ + + int fd() const; ///< Get file descriptor + /**< Returns the file descriptor this protocol instance + references. This is the same as fh().fd() but + is implemented here since it is needed so often. */ + + void fd(int) const; ///< Initialize file descriptor + /**< Assigns the file descriptor to the file handle, this + protocol instance references. Only valid, if the file + handle has not yet been assigned any descriptor (To + change the file descriptor association later, use \c + ::dup2()). */ private: - // backpointer to owning SocketBody instance - SocketBody * body_; - friend class SocketBody; - }; + virtual std::auto_ptr clone(bool isServer) const = 0; + virtual std::auto_ptr clone(int fd, bool isServer) const = 0; + virtual SocketBody & body() const = 0; + + friend class SocketBody; + }; + + template class ClientSocketHandle; + template class ServerSocketHandle; + + /** \brief Concrete Socket Protocol implementation base class - template + ConcreteSocketProtocol is the base class of a concrete socket protocol implementation. The + final protocol class must inherit from ConcreteSocketProtocol. The template argument \a + SocketPolicy must be set to the complete socket policy of the protocol. \a Self is the name + of the final protocol class which inherits this class. + + A protocol implementation may define the protocol interface directly. It can also + (additionally) make use of multiple inheritance to combine a set of protocol facets into a + specific protocol implementation (i.e. TCPv4SocketProtocol inherits from + ConcreteSocketProtocol and from the protocol facets IPv4SocketProtocol, TCPSocketProtocol, + BSDSocketProtocol and AddressableBSDSocketProtocol). The protocol facets are not concrete + protocols themselves, they are combined to build concrete protocols. This structure will + remove a lot of code duplication. It is important to ensure, that the protocol facets do not + overlap, since otherwise there will be problems resolving overlapping members. + + \doc init_client init_server + */ + template class ConcreteSocketProtocol : public virtual SocketProtocol { @@ -83,7 +279,7 @@ namespace lib { /////////////////////////////////////////////////////////////////////////// // Types - typedef SocketPolicy Policy; + typedef SocketPolicy Policy; ///< The protocols policy /////////////////////////////////////////////////////////////////////////// ///\name Structors and default members @@ -99,15 +295,27 @@ namespace lib { /////////////////////////////////////////////////////////////////////////// Policy const & policy() const; - + protected: + ClientSocketHandle clientHandle() const; + ///< Get client handle for associated socket + /**< Returns a client handle for the socket associated with + this protocol instance */ + ServerSocketHandle serverHandle() const; + ///< Get server handle for associated socket + /**< Returns a server handle for the socket associated with + this protocol instance */ private: - Policy policy_; + virtual std::auto_ptr clone(bool isServer) const; + virtual std::auto_ptr clone(int fd, bool isServer) const; + virtual SocketBody & body() const; + Policy policy_; }; -}} + /// @} +} ///////////////////////////////hh.e//////////////////////////////////////// #include "SocketProtocol.cci" @@ -118,5 +326,10 @@ namespace lib { // Local Variables: // mode: c++ -// c-file-style: "satcom" +// fill-column: 100 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// comment-column: 40 // End: