X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Socket%2FClientSocketHandle.hh;h=92635f956927c221c820ce60de7bc32402d7d64d;hb=bd9f9d3fd6fbcff0112a7bf48ab9284da9576b11;hp=3c836a4b6d36571980129d30455b8219b0c38d5f;hpb=aec1302f91b51edb58f8a97985ab2e0aa9c8db66;p=senf.git diff --git a/Socket/ClientSocketHandle.hh b/Socket/ClientSocketHandle.hh index 3c836a4..92635f9 100644 --- a/Socket/ClientSocketHandle.hh +++ b/Socket/ClientSocketHandle.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 @@ -21,112 +21,122 @@ // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** \file - \brief senf::ClientSocketHandle public header + \brief ClientSocketHandle public header */ -#ifndef HH_ClientSocketHandle_ -#define HH_ClientSocketHandle_ 1 +#ifndef HH_SENF_Socket_ClientSocketHandle_ +#define HH_SENF_Socket_ClientSocketHandle_ 1 // Custom includes #include +#include +#include +#include #include "SocketHandle.hh" //#include "ClientSocketHandle.mpp" ///////////////////////////////hh.p//////////////////////////////////////// namespace senf { - + /// \addtogroup handle_group /// @{ - - template class ServerSocketHandle; + + template class ServerSocketHandle; /** \brief Generic SocketHandle with client interface - - This class provides the client side policy interface of the socket - abstraction. ClientSocketHandle defines the complete policy interface. It does not implement - any functionality itself however. All calls are forward to the following policy classes: - - - - - - - - - - - - - -
ClientSocketHandle member Policy member
read() ReadPolicy::read (\ref senf::ReadPolicyBase)
readfrom() ReadPolicy::readfrom (\ref senf::ReadPolicyBase)
write() WritePolicy::write (\ref senf::WritePolicyBase)
writeto() WritePolicy::writeto (\ref senf::WritePolicyBase)
connect() AddressingPolicy::connect (\ref senf::AddressingPolicyBase)
bind() AddressingPolicy::bind (\ref senf::AddressingPolicyBase)
peer() AddressingPolicy::peer (\ref senf::AddressingPolicyBase)
local() AddressingPolicy::local (\ref senf::AddressingPolicyBase)
rcvbuf() BufferingPolicy::sndbuf (\ref senf::BufferingPolicyBase)
sndbuf() BufferingPolicy::rcvbuf (\ref senf::BufferingPolicyBase)
- - It is important to note, that not all members are always accessible. Which are depends on - the \c Policy template argument. If any of the policy axis is left unspecified the - corresponding members will not be callable (you will get a compile time error). Even if - every policy axis is defined, some members might (and will) not exist if they are - meaningless for the protocol of the socket. This depends on the exact policy. - - To find out, which members are available, you have to check the documentation of the policy - classes. You can also find a summary of all members available in the leaf protocol class - documentation. - - \todo Move all not template-parameter dependent code into a non-template base class - - \idea Give SocketHandle (and therefore ClientSocketHandle and ServerSocketHandle) a \c - protocol() template member and an additional template arg \c Policies. This arg should be a - typelist of Poclicy classes which can be accessed. You use protocol() to - access a protocol class. \c Policies can of course be underspecified or even empty. - - \idea add more flexible read/write members for a) boost::arrays and arrays of other types b) - std::vector (which uses contiguous memory ..) c) other random-access containers (we should - use some configurable trait class to identify containers with contiguous storage). Probably - we should just use a generic Boost.Range interface. Here we again come to the point: make - all except the most basic members be non-member algorithms ? this would make the - configuration of such extenden members more flexible. - - \see \ref policy_group \n + + This class provides the client side policy interface of the socket + abstraction. ClientSocketHandle defines the complete policy interface. It does not implement + any functionality itself however. The following table shows, to which policy members each + group of ClientSocketHandle members is forwardd. The last collumn shows, on which other + policies this member-group depends in the default policy classes. If you define + your own policy classes, the dependencies are up to you. + + + + + + + + + + + +
ClientSocketHandle member Policy member Other policies
read() ReadPolicy::read (\ref senf::ReadPolicyBase)
readfrom() ReadPolicy::readfrom (\ref senf::ReadPolicyBase) UnconnectedCommunicationPolicy
write() WritePolicy::write (\ref senf::WritePolicyBase) ConnectedCommunicationPolicy
writeto() WritePolicy::writeto (\ref senf::WritePolicyBase) UnconnectedCommunicationPolicy
connect() AddressingPolicy::connect (\ref senf::AddressingPolicyBase)
bind() AddressingPolicy::bind (\ref senf::AddressingPolicyBase)
peer() AddressingPolicy::peer (\ref senf::AddressingPolicyBase)
local() AddressingPolicy::local (\ref senf::AddressingPolicyBase)
+ + It is important to note, that not all members are always accessible. Which are depends on + the \c Policy template argument. If any of the policy axis is left unspecified the + corresponding members will not be callable (you will get a compile time error). Even if + every policy axis is defined, some members might (and will) not exist if they are + meaningless for the protocol of the socket. This depends on the exact policy. + + To find out, which members are available, you have to check the documentation of the policy + classes. You can also find a summary of all members available in the leaf protocol class + documentation. + + \todo Move all not template-parameter dependent code into a non-template base class + + \idea Give SocketHandle (and therefore ClientSocketHandle and ServerSocketHandle) a \c + protocol() template member and an additional template arg \c Policies. This arg should be a + typelist of Poclicy classes which can be accessed. You use protocol() to + access a protocol class. \c Policies can of course be underspecified or even empty. + + \see \ref policy_group \n \ref protocol_group */ - template + template class ClientSocketHandle - : public SocketHandle + : public SocketHandle { public: /////////////////////////////////////////////////////////////////////////// // Types - /// Address type from the addressing policy - typedef typename Policy::AddressingPolicy::Address Address; - /// 'Best' type for passing address as parameter - /** Depending on the type of \c Address, this will be either Address or Address - const &. See call_traits documentation in the Boost.Utility library\endlink. - */ + /// Address type from the addressing policy + typedef typename SPolicy::AddressingPolicy::Address Address; + /// 'Best' type for passing address as parameter + /** Depending on the type of \c Address, this will be either Address or Address + const &. See call_traits documentation in + the Boost.Utility library. + */ typedef typename boost::call_traits
::param_type AddressParam; - /// Corresponding server socket handle with the same policy - /** This class will probably only be usable, if the \c CommunicationPolicy is \c - ConnectedCommunicationPolicy and the \c AddressingPolicy is not \c - NoAddressingPolicy. */ - typedef ServerSocketHandle ServerSocketHandle; + /// Corresponding server socket handle with the same policy + /** This class will probably only be usable, if the \c CommunicationPolicy is \c + ConnectedCommunicationPolicy and the \c AddressingPolicy is not \c + NoAddressingPolicy. */ + typedef ServerSocketHandle ServerHandle; /////////////////////////////////////////////////////////////////////////// ///\name Structors and default members ///@{ - // no default constructor + // default default constructor // default copy constructor // default copy assignment // default destructor + // here to implement + ClientSocketHandle(); + // conversion constructors +# ifndef DOXYGEN template ClientSocketHandle(ClientSocketHandle other, - typename SocketHandle::template IsCompatible::type * = 0); + typename SocketHandle::template IsCompatible::type * = 0); +# else + ClientSocketHandle(ClientSocketHandle other); +# endif +# ifndef DOXYGEN template - typename SocketHandle::template IsCompatible::type const & + typename SocketHandle::template IsCompatible::type const & operator=(ClientSocketHandle other); +# else + template + ClientSocketHandle const & operator=(ClientSocketHandle other); +# endif ///@} /////////////////////////////////////////////////////////////////////////// @@ -135,247 +145,296 @@ namespace senf { ///\name Reading and Writing ///@{ - /** \brief Read data from socket + /** \brief Read data from socket - If the sockets \c FramingPolicy is \c DatagramFramingPolicy, every read() command will - return a single datagram. If the sockets FramingPolicy is StreamFraming, the operation will - return as much data as possible from the socket buffer. However it cannot be guaranteed, - that the socket buffer will be empty after read() returns. + If the sockets \c FramingPolicy is \c DatagramFramingPolicy, every read() command will + return a single datagram. If the sockets FramingPolicy is StreamFraming, the operation + will return as much data as possible from the socket buffer. However it cannot be + guaranteed, that the socket buffer will be empty after read() returns. - \attention If the space available for the data read is limited, the read will return no - more than that amount of data. For a datagram socket, a full datagram is still dequed - from the socket buffer, the remainder of the datagram will be lost. + \attention If the space available for the data read is limited, the read will return no + more than that amount of data. For a datagram socket, a full datagram is still dequeued + from the socket buffer, the remainder of the datagram will be lost. - There are three variants of read which differ in how they return the read string. + There are several variants of read which differ in how they return the read string. - \throws senf::SystemException + If the further document doesn't tell something differently, on a blocking socket the + members will \e always return some data (as long as the socket has not been closed at + the other end) and will block, if no data is available now. If you do not want to block, + you \e must make the socket non-blocking (using FileHandle::blocking()). + \throws senf::SystemException - This variant will read up to \c limit bytes from the - socket and return them as a \c std::string object. - On a blocking socket, this member will \e always return some data (as long as the socket - has not been closed at the other end) and will block, if no data is available now. If - you do not want to block, you \e must make the socket non-blocking (using - FileHandle::blocking()). + This variant will read up to \c limit bytes from the + socket and return them as a \c std::string object. - \param[in] limit Maximum number of bytes to read or 0 if unlimited. - \returns data read - - \implementation The read() family of members will use standard POSIX \c read calls, not - \c recv. - */ + \param[in] limit Maximum number of bytes to read or 0 if unlimited. + \returns data read + + \implementation The read() family of members will use standard POSIX \c read calls, not + \c recv. + */ std::string read (unsigned limit=0); - void read (std::string & buffer, unsigned limit=0); - ///< Read data into string buffer - /**< On a blocking socket, this member will \e always return - some data (as long as the socket has not been closed at - the other end) and will block, if no data is available - now. If you do not want to block, you \e must make the - socket non-blocking (using FileHandle::blocking()). - \param[out] buffer data read - \param[in] limit Maximum number of buytes to read or 0 - if unlimited - \see \ref read() */ - unsigned read (char * buffer, unsigned size); + template +# ifndef DOXYGEN + typename boost::range_iterator::type + read (ForwardWritableRange const & range, + typename boost::disable_if< boost::is_convertible >::type * = 0); +# else + typename boost::range_iterator::type + read (ForwardWritableRange const & range); + ///< Read data into range + /**< Read data into the given range. At most + boost::size(range) characters are read. The + data read will start at the beginning of the + range. read returns a past-the-end iterator after the + last character read. This iterator will point to + somewhere within the input range. + \param[in,out] range Range to store data in + \returns past-the-end iterator pointer to after the + last read character + \see \ref read() \n + Boost.Range */ +# endif +# ifndef DOXYGEN + template + typename boost::range_iterator::type + read (ForwardWritableRange & range, + typename boost::disable_if< boost::is_convertible >::type * = 0); +# else + template + typename boost::range_iterator::type + read (ForwardWritableRange & range); + ///< Read data into range + /**< \see read(ForwardWritableRange const &) \n + read() \n + Boost.Range */ +# endif + template + void read (Sequence & container, unsigned limit); + ///< Read data into container + /**< The data read is written into the given container. Old + data in the container will be removed. For this to + work, the container must be a model of 'Sequence' as + defined in the STL documentation + \param[out] container Container to write data to + \param[in] limit Maximum number of characters to read + \see \ref read() */ + char * read (char * start, char * end); ///< Read data into memory area - /**< This variant will read data into the memory area at \c - buffer of size \c size. This is the most performant - version of read(). - \param[in] buffer address of buffer to store data at - \param[in] size size of memory buffer - \returns Number of bytes read - \see \ref read() */ - - /** \brief Read data from unconnected socket returning address - - This member behaves like read() but should only be available, if the sockets \c - CommunicationPolicy is \c UnconnectedCommunicationPolicy and the \c AddressingPolicy is - not \c NoAddressingPolicy. The readfrom() family will in addition to the data return the - address of the sender. - - \throws senf::SystemException - - This variant will return the data read and the address as a std::pair. - - \returns \c std::pair of data read (a string) and the peers address - - \todo Add \c limit argument - - \implementation The readfrom() family of members will use \c recvfrom from the BSD - socket API. - */ - std::pair - readfrom (); - void readfrom (std::string & buffer, Address & from); - ///< Read data into string buffer - /**< This variant will return the result in the locations - passed in - \param[out] buffer data read - \param[out] from peer address - \see \ref readfrom() */ - unsigned readfrom (char * buffer, unsigned size, Address & from); - ///< Read data into memory byffer - /**< This variant will read data into the memory area at \c - buffer of size \c size. This is the most performant - version of readfrom(). - \param[in] buffer address of buffer to store data at - \param[in] size size of bnuffer - \param[out] from peer address - \returns Number of bytes read - \see \ref readfrom() */ - - - /** \brief Write data to socket - - The write() family of members will write out the data to the socket. If the sockets \c - FramingPolicy is \c DatagramFramingPolicy, every write() call will result in one - datagram. - - A single write call might depending on the circumstances write only part of the data. - - There are two variants of thie member - - \throws senf::SystemException - - - This variant will write out the string \c data. - - \param[in] data Data to write - \returns number of bytes written - \todo Make this member write the complete string if the socket is blocking - \implementation The write() family of members will use POSIX \c write calls, not \c - send. - */ - unsigned write (std::string const & data); - unsigned write (char const * buffer, unsigned size); + /**< This variant will read data into the memory area from + \a start to before \a end. This is guaranteed to be the + most efficient version of read(). + \param[in] start address of buffer to store data at + \param[in] end address one past the end of the buffer + \returns pointer past the end of the data read + \see \ref read() */ + + /** \brief Read data from unconnected socket returning address + + The readfrom() group of member behaves like \ref read() but should only be available, if + the sockets \c CommunicationPolicy is \c UnconnectedCommunicationPolicy and the \c + AddressingPolicy is not \c NoAddressingPolicy. readfrom() will in addition to the data + return the address of the sender. + + \throws senf::SystemException + + + This variant will return the data read and the address as a std::pair. + + \returns \c std::pair of data read (a string) and the peers address + + \implementation The readfrom() family of members will use \c recvfrom from the BSD + socket API. + */ + std::pair + readfrom (unsigned limit=0); + template + typename boost::range_iterator::type + readfrom (ForwardWritableRange const & range, Address & from); + ///< Read data into range + /**< Read data into the given range. At most + boost::size(range) characters are read. The + data read will start at the beginning of the + range. read returns a past-the-end iterator after the + last character read. This iterator will point to + somewhere within the input range. + \param[in,out] range Range to store data in + \param[out] from peers address from which the data was + received + \returns past-the-end iterator pointer to after the + last read character + \see \ref readfrom() \n + Boost.Range */ + template + typename boost::range_iterator::type + readfrom (ForwardWritableRange & range, Address & from); + ///< Read data into range + /**< \see readfrom(ForwardWritableRange const&,Address&) \n + readfrom() \n + Boost.Range */ + template + void readfrom (Sequence & container, Address & from, unsigned limit); + ///< Read data into container + /**< The data read is written into the given container. Old + data in the container will be removed. For this to + work, the container must be a model of 'Sequence' as + defined in the STL documentation + \param[out] container Container to write data to + \param[in] limit Maximum number of characters to read + \param[out] from peers address from which the data was + received + \see \ref readfrom() */ + char * readfrom (char * start, char * end, Address & from); + ///< Read data into memory buffer + /**< This variant will read data into the memory area from + \a start to before \a end. This is guaranteed to be the + most efficient version of readfrom(). + \param[in] start address of buffer to store data at + \param[in] end address one past the end of the buffer + \param[out] from peers address from which the data was + received + \returns pointer past the end of the data read + \see \ref read() */ + + + /** \brief Write data to socket + + The write() family of members will write out the data to the socket. If the sockets \c + FramingPolicy is \c DatagramFramingPolicy, every write() call will result in one + datagram. + + A single write call might depending on the circumstances write only part of the data. + + There are two variants of this member + + \throws senf::SystemException + + + This variant will write out the range \c data. + + \param[in] range Data to write + \returns past-the-end iterator after last element written + \implementation The write() family of members will use POSIX \c write calls, not \c + send. + */ + template + typename boost::range_const_iterator::type + write (ForwardReadableRange const & range); + char const * write (char const * start, char const * end); ///< Write data to socket from memory buffer - /**< \param[in] buffer address of buffer to write - \param[in] size amount of data to write - \returns Number of bytes written - \see \ref write() */ + /**< \param[in] start beginning of area to write + \param[in] end past-the-end pointer to area to write + \returns past-the-end pointer after last byte written + \see \ref write() \n + Boost.Range */ + + /** \brief Write data to unconnected socket - /** \brief Write data to unconnected socket + This member behaves like write() but should only be available, if the sockets \c + CommunicationPolicy is \c UnconnectedCommunicationPolicy and the \c AddressingPolicy is + not \c NoAddressingPolicy. The writeto() family of members takes the target address as + an additional argument. - This member behaves like write() but should only be available, if the sockets \c - CommunicationPolicy is \c UnconnectedCommunicationPolicy and the \c AddressingPolicy is - not \c NoAddressingPolicy. The writeto() family of members takes the target address as - an additional argument. + There are two variants of this member. - There are two variants of this member. + \throw senf::SystemException - \throw senf::SystemException - - This variant will send the string \c data to the peer \c addr. + This variant will send the range \c range to peer \c addr. - \param[in] addr Address of peer to send data to - \param[in] data data to send - \returns Number of bytes written - */ - unsigned writeto (AddressParam addr, std::string const & data); - unsigned writeto (AddressParam addr, char const * buffer, unsigned size); + \param[in] addr Address of peer to send data to + \param[in] range data to send + \returns Number of bytes written + */ + template + typename boost::range_const_iterator::type + writeto (AddressParam addr, ForwardReadableRange const & range); + char const * writeto (AddressParam addr, char const * start, char const * end); ///< Write data from memory buffer to unconnected socket - /**< \param[in] addr Address o fpeer to send data to - \param[in] buffer address of buffer to write - \param[in] size amount of data to write - \returns Number of bytes written - \see \ref writeto() */ + /**< \param[in] addr Address of peer to send data to + \param[in] start address of buffer to write + \param[in] end past-the-end pointer after data to write + \returns past-the-end iterator after last byte written + \see \ref writeto() \n + Boost.Range */ - /////////////////////////////////////////////////////////////////////////// - ///\name Addressing - ///@{ + /////////////////////////////////////////////////////////////////////////// + ///\name Addressing + ///@{ - /** \brief Connect to remote peer + /** \brief Connect to remote peer - This member will establish a connection for addressable connection-oriented protocols - (that is, the CommunicationPolicy is ConnectedCommunicationPolicy and the - AddressingPolicy is not NoAddressingPolicy). + This member will establish a connection for addressable connection-oriented protocols + (that is, the CommunicationPolicy is ConnectedCommunicationPolicy and the + AddressingPolicy is not NoAddressingPolicy). - \param[in] addr Address to connect to + \param[in] addr Address to connect to - \throws senf::SystemException - */ - void connect (AddressParam addr); + \throws senf::SystemException + */ + void connect (AddressParam addr) const; - /** \brief Set local address - - For addressable protocols (AddressingPolicy is not NoAddressingPolicy), bind() will set - the local address of the socket. + /** \brief Set local address - \parm[in] addr Local socket address to asign + For addressable protocols (AddressingPolicy is not NoAddressingPolicy), bind() will set + the local address of the socket. - \throws senf::SystemException - */ - void bind (AddressParam addr); + \param[in] addr Local socket address to assign - /** \brief Query remote address + \throws senf::SystemException + */ + void bind (AddressParam addr) const; - This member will return the address of the communication partner in addressable - connection-oriented protocols (that is, the CommunicationPolicy is - ConnectedCommunicationPolicy and the AddressingPolicy is not NoAddressingPolicy). + /** \brief Query remote address - There are two Variants of this member, one will return the address by value, the other - takes a reference argument to elide the copy operation. + This member will return the address of the communication partner in addressable + connection-oriented protocols (that is, the CommunicationPolicy is + ConnectedCommunicationPolicy and the AddressingPolicy is not NoAddressingPolicy). - \throws senf::SystemException - */ - Address peer (); - void peer (Address & addr); + There are two Variants of this member, one will return the address by value, the other + takes a reference argument to elide the copy operation. + + \throws senf::SystemException + */ + Address peer () const; + void peer (Address & addr) const; ///< Query remote address /**< \see \ref peer() */ - /** \brief Query local address + /** \brief Query local address - This member will return the address of the local socket in addressable protocols - (AddressingPolicy is not NoAddressingPolicy). + This member will return the address of the local socket in addressable protocols + (AddressingPolicy is not NoAddressingPolicy). - There are two Variants of this member, one will return the address by value, the other - takes a reference argument to elide the copy operation. + There are two Variants of this member, one will return the address by value, the other + takes a reference argument to elide the copy operation. - \throws senf::SystemException - */ - Address local (); - void local (Address & addr); + \throws senf::SystemException + */ + Address local () const; + void local (Address & addr) const; ///< Query local address /**< \see \ref local() */ - ///@} - - /////////////////////////////////////////////////////////////////////////// - ///\name Buffering - ///@{ - - unsigned rcvbuf (); ///< Check size of receive buffer - /**< \returns size of receive buffer in bytes */ - void rcvbuf (unsigned size); - ///< Set size of receive buffer - /**< \param[in] size size of receive buffer in bytes */ - - unsigned sndbuf (); ///< Check size of send buffer - /**< \returns size of send buffer in bytes */ - void sndbuf (unsigned size); - ///< Set size of send buffer - /**< \param[in] size size of send buffer in bytes */ + ///@} - ///@} + static ClientSocketHandle cast_static(FileHandle handle); + static ClientSocketHandle cast_dynamic(FileHandle handle); - static ClientSocketHandle cast_static(FileHandle handle); - static ClientSocketHandle cast_dynamic(FileHandle handle); + // we need to override both since SocketHandle is *not* polymorphic + void state(SocketStateMap & map, unsigned lod=0); + std::string dumpState(unsigned lod=0); - // we need to override both since SocketHandle is *not* polymorphic - void state(SocketStateMap & map, unsigned lod=0); - std::string dumpState(unsigned lod=0); + unsigned available(); protected: - ClientSocketHandle(FileHandle other, bool isChecked); - explicit ClientSocketHandle(std::auto_ptr protocol, - int fd = -1); + ClientSocketHandle(FileHandle other, bool isChecked); + explicit ClientSocketHandle(std::auto_ptr body); private: - unsigned available(); - - friend class senf::ServerSocketHandle; + friend class senf::ServerSocketHandle; }; /// @} @@ -390,6 +449,10 @@ namespace senf { // Local Variables: // mode: c++ -// c-file-style: "senf" // fill-column: 100 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// comment-column: 40 // End: