4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 // Stefan Bund <stefan.bund@fokus.fraunhofer.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 \brief ClientSocketHandle public header
27 #ifndef HH_ClientSocketHandle_
28 #define HH_ClientSocketHandle_ 1
31 #include <boost/call_traits.hpp>
32 #include <boost/range.hpp>
33 #include <boost/utility.hpp>
34 #include <boost/type_traits.hpp>
35 #include "SocketHandle.hh"
37 //#include "ClientSocketHandle.mpp"
38 ///////////////////////////////hh.p////////////////////////////////////////
42 /// \addtogroup handle_group
45 template <class Policy> class ServerSocketHandle;
47 /** \brief Generic SocketHandle with client interface
49 This class provides the client side policy interface of the socket
50 abstraction. ClientSocketHandle defines the complete policy interface. It does not implement
51 any functionality itself however. The following table shows, to which policy members each
52 group of ClientSocketHandle members is forwardd. The last collumn shows, on which other
53 policies this member-group depends <em>in the default policy classes</em>. If you define
54 your own policy classes, the dependencies are up to you.
57 <tr><th>ClientSocketHandle member</th> <th>Policy member</th> <th>Other policies</th></tr>
58 <tr><td>read()</td> <td>ReadPolicy::read (\ref senf::ReadPolicyBase)</td> <td></td></tr>
59 <tr><td>readfrom()</td> <td>ReadPolicy::readfrom (\ref senf::ReadPolicyBase)</td> <td>UnconnectedCommunicationPolicy</td></tr>
60 <tr><td>write()</td> <td>WritePolicy::write (\ref senf::WritePolicyBase)</td> <td>ConnectedCommunicationPolicy</td></tr>
61 <tr><td>writeto()</td> <td>WritePolicy::writeto (\ref senf::WritePolicyBase)</td> <td>UnconnectedCommunicationPolicy</td></tr>
62 <tr><td>connect()</td> <td>AddressingPolicy::connect (\ref senf::AddressingPolicyBase)</td> <td></td></tr>
63 <tr><td>bind()</td> <td>AddressingPolicy::bind (\ref senf::AddressingPolicyBase)</td> <td></td></tr>
64 <tr><td>peer()</td> <td>AddressingPolicy::peer (\ref senf::AddressingPolicyBase)</td> <td></td></tr>
65 <tr><td>local()</td> <td>AddressingPolicy::local (\ref senf::AddressingPolicyBase)</td> <td></td></tr>
66 <tr><td>rcvbuf()</td> <td>BufferingPolicy::sndbuf (\ref senf::BufferingPolicyBase)</td> <td></td></tr>
67 <tr><td>sndbuf()</td> <td>BufferingPolicy::rcvbuf (\ref senf::BufferingPolicyBase)</td> <td></td></tr>
70 It is important to note, that not all members are always accessible. Which are depends on
71 the \c Policy template argument. If any of the policy axis is left unspecified the
72 corresponding members will not be callable (you will get a compile time error). Even if
73 every policy axis is defined, some members might (and will) not exist if they are
74 meaningless for the protocol of the socket. This depends on the exact policy.
76 To find out, which members are available, you have to check the documentation of the policy
77 classes. You can also find a summary of all members available in the leaf protocol class
80 \todo Move all not template-parameter dependent code into a non-template base class
82 \idea Give SocketHandle (and therefore ClientSocketHandle and ServerSocketHandle) a \c
83 protocol() template member and an additional template arg \c Policies. This arg should be a
84 typelist of Poclicy classes which can be accessed. You use protocol<ProtocolClass>() to
85 access a protocol class. \c Policies can of course be underspecified or even empty.
87 \see \ref policy_group \n
90 \fixme Add enable_if conditions so anything convertible to unsigned will not be interpreted
91 as a Range template argument but will use the unsigned variant of
92 read/readfrom/write/writeto.
94 template <class Policy>
95 class ClientSocketHandle
96 : public SocketHandle<Policy>
99 ///////////////////////////////////////////////////////////////////////////
102 /// Address type from the addressing policy
103 typedef typename Policy::AddressingPolicy::Address Address;
104 /// 'Best' type for passing address as parameter
105 /** Depending on the type of \c Address, this will be either <tt>Address</tt> or <tt>Address
107 href="http://www.boost.org/libs/utility/call_traits.htm">call_traits documentation in
108 the Boost.Utility library.</a>
110 typedef typename boost::call_traits<Address>::param_type AddressParam;
111 /// Corresponding server socket handle with the same policy
112 /** This class will probably only be usable, if the \c CommunicationPolicy is \c
113 ConnectedCommunicationPolicy and the \c AddressingPolicy is not \c
114 NoAddressingPolicy. */
115 typedef ServerSocketHandle<Policy> ServerSocketHandle;
117 ///////////////////////////////////////////////////////////////////////////
118 ///\name Structors and default members
121 // default default constructor
122 // default copy constructor
123 // default copy assignment
124 // default destructor
127 ClientSocketHandle();
129 // conversion constructors
130 template <class OtherPolicy>
131 ClientSocketHandle(ClientSocketHandle<OtherPolicy> other,
132 typename SocketHandle<Policy>::template IsCompatible<OtherPolicy>::type * = 0);
134 template <class OtherPolicy>
135 typename SocketHandle<Policy>::template IsCompatible<OtherPolicy>::type const &
136 operator=(ClientSocketHandle<OtherPolicy> other);
139 ///////////////////////////////////////////////////////////////////////////
141 ///////////////////////////////////////////////////////////////////////////
142 ///\name Reading and Writing
145 /** \brief Read data from socket
147 If the sockets \c FramingPolicy is \c DatagramFramingPolicy, every read() command will
148 return a single datagram. If the sockets FramingPolicy is StreamFraming, the operation
149 will return as much data as possible from the socket buffer. However it cannot be
150 guaranteed, that the socket buffer will be empty after read() returns.
152 \attention If the space available for the data read is limited, the read will return no
153 more than that amount of data. For a datagram socket, a full datagram is still dequeued
154 from the socket buffer, the remainder of the datagram will be lost.
156 There are several variants of read which differ in how they return the read string.
158 If the further document doesn't tell something differently, on a blocking socket the
159 members will \e always return some data (as long as the socket has not been closed at
160 the other end) and will block, if no data is available now. If you do not want to block,
161 you \e must make the socket non-blocking (using FileHandle::blocking()).
163 \throws senf::SystemException
166 This variant will read up to \c limit bytes from the
167 socket and return them as a \c std::string object.
169 \param[in] limit Maximum number of bytes to read or 0 if unlimited.
172 \implementation The read() family of members will use standard POSIX \c read calls, not
175 std::string read (unsigned limit=0);
176 template <class ForwardWritableRange>
177 typename boost::range_iterator<ForwardWritableRange>::type
178 read (ForwardWritableRange const & range,
179 typename boost::disable_if< boost::is_convertible<ForwardWritableRange,unsigned> >::type * = 0);
180 ///< Read data into range
181 /**< Read data into the given range. At most
182 <tt>boost::size(range)</tt> characters are read. The
183 data read will start at the beginning of the
184 range. read returns a past-the-end iterator after the
185 last character read. This iterator will point to
186 somewhere within the input range.
187 \param[in,out] range Range to store data in
188 \returns past-the-end iterator pointer to after the
191 <a href="http://www.boost.org/libs/range/index.html">Boost.Range</a> */
192 template <class ForwardWritableRange>
193 typename boost::range_iterator<ForwardWritableRange>::type
194 read (ForwardWritableRange & range,
195 typename boost::disable_if< boost::is_convertible<ForwardWritableRange,unsigned> >::type * = 0);
196 ///< Read data into range
197 /**< \see read(ForwardWritableRange const &) \n
199 <a href="http://www.boost.org/libs/range/index.html">Boost.Range</a> */
200 template <class Sequence>
201 void read (Sequence & container, unsigned limit);
202 ///< Read data into container
203 /**< The data read is written into the given container. Old
204 data in the container will be removed. For this to
205 work, the container must be a model of 'Sequence' as
206 defined in the STL documentation
207 \param[out] container Container to write data to
208 \param[in] limit Maximum number of characters to read
210 char * read (char * start, char * end);
211 ///< Read data into memory area
212 /**< This variant will read data into the memory area from
213 \a start to before \a end. This is guaranteed to be the
214 most efficient version of read().
215 \param[in] start address of buffer to store data at
216 \param[in] end address one past the end of the buffer
217 \returns pointer past the end of the data read
220 /** \brief Read data from unconnected socket returning address
222 The readfrom() group of member behaves like \ref read() but should only be available, if
223 the sockets \c CommunicationPolicy is \c UnconnectedCommunicationPolicy and the \c
224 AddressingPolicy is not \c NoAddressingPolicy. readfrom() will in addition to the data
225 return the address of the sender.
227 \throws senf::SystemException
230 This variant will return the data read and the address as a std::pair.
232 \returns \c std::pair of data read (a string) and the peers address
234 \implementation The readfrom() family of members will use \c recvfrom from the BSD
237 std::pair<std::string, Address>
238 readfrom (unsigned limit=0);
239 template <class ForwardWritableRange>
240 typename boost::range_iterator<ForwardWritableRange const>::type
241 readfrom (ForwardWritableRange const & range, Address & from);
242 ///< Read data into range
243 /**< Read data into the given range. At most
244 <tt>boost::size(range)</tt> characters are read. The
245 data read will start at the beginning of the
246 range. read returns a past-the-end iterator after the
247 last character read. This iterator will point to
248 somewhere within the input range.
249 \param[in,out] range Range to store data in
250 \param[out] from peers address from which the data was
252 \returns past-the-end iterator pointer to after the
254 \see \ref readfrom() \n
255 <a href="http://www.boost.org/libs/range/index.html">Boost.Range</a> */
256 template <class ForwardWritableRange>
257 typename boost::range_iterator<ForwardWritableRange>::type
258 readfrom (ForwardWritableRange & range, Address & from);
259 ///< Read data into range
260 /**< \see readfrom(ForwardWritableRange const&,Address&) \n
262 <a href="http://www.boost.org/libs/range/index.html">Boost.Range</a> */
263 template <class Sequence>
264 void readfrom (Sequence & container, Address & from, unsigned limit);
265 ///< Read data into container
266 /**< The data read is written into the given container. Old
267 data in the container will be removed. For this to
268 work, the container must be a model of 'Sequence' as
269 defined in the STL documentation
270 \param[out] container Container to write data to
271 \param[in] limit Maximum number of characters to read
272 \param[out] from peers address from which the data was
274 \see \ref readfrom() */
275 char * readfrom (char * start, char * end, Address & from);
276 ///< Read data into memory buffer
277 /**< This variant will read data into the memory area from
278 \a start to before \a end. This is guaranteed to be the
279 most efficient version of readfrom().
280 \param[in] start address of buffer to store data at
281 \param[in] end address one past the end of the buffer
282 \param[out] from peers address from which the data was
284 \returns pointer past the end of the data read
288 /** \brief Write data to socket
290 The write() family of members will write out the data to the socket. If the sockets \c
291 FramingPolicy is \c DatagramFramingPolicy, every write() call will result in one
294 A single write call might depending on the circumstances write only part of the data.
296 There are two variants of this member
298 \throws senf::SystemException
301 This variant will write out the range \c data.
303 \param[in] range Data to write
304 \returns past-the-end iterator after last element written
305 \implementation The write() family of members will use POSIX \c write calls, not \c
308 template <class ForwardReadableRange>
309 typename boost::range_const_iterator<ForwardReadableRange const>::type
310 write (ForwardReadableRange const & range);
311 char const * write (char const * start, char const * end);
312 ///< Write data to socket from memory buffer
313 /**< \param[in] start beginning of area to write
314 \param[in] end past-the-end pointer to area to write
315 \returns past-the-end pointer after last byte written
317 <a href="http://www.boost.org/libs/range/index.html">Boost.Range</a> */
319 /** \brief Write data to unconnected socket
321 This member behaves like write() but should only be available, if the sockets \c
322 CommunicationPolicy is \c UnconnectedCommunicationPolicy and the \c AddressingPolicy is
323 not \c NoAddressingPolicy. The writeto() family of members takes the target address as
324 an additional argument.
326 There are two variants of this member.
328 \throw senf::SystemException
331 This variant will send the range \c range to peer \c addr.
333 \param[in] addr Address of peer to send data to
334 \param[in] range data to send
335 \returns Number of bytes written
337 template <class ForwardReadableRange>
338 typename boost::range_const_iterator<ForwardReadableRange const>::type
339 writeto (AddressParam addr, ForwardReadableRange const & range);
340 char const * writeto (AddressParam addr, char const * start, char const * end);
341 ///< Write data from memory buffer to unconnected socket
342 /**< \param[in] addr Address of peer to send data to
343 \param[in] start address of buffer to write
344 \param[in] end past-the-end pointer after data to write
345 \returns past-the-end iterator after last byte written
346 \see \ref writeto() \n
347 <a href="http://www.boost.org/libs/range/index.html">Boost.Range</a> */
349 ///////////////////////////////////////////////////////////////////////////
353 /** \brief Connect to remote peer
355 This member will establish a connection for addressable connection-oriented protocols
356 (that is, the CommunicationPolicy is ConnectedCommunicationPolicy and the
357 AddressingPolicy is not NoAddressingPolicy).
359 \param[in] addr Address to connect to
361 \throws senf::SystemException
363 void connect (AddressParam addr);
365 /** \brief Set local address
367 For addressable protocols (AddressingPolicy is not NoAddressingPolicy), bind() will set
368 the local address of the socket.
370 \param[in] addr Local socket address to asign
372 \throws senf::SystemException
374 void bind (AddressParam addr);
376 /** \brief Query remote address
378 This member will return the address of the communication partner in addressable
379 connection-oriented protocols (that is, the CommunicationPolicy is
380 ConnectedCommunicationPolicy and the AddressingPolicy is not NoAddressingPolicy).
382 There are two Variants of this member, one will return the address by value, the other
383 takes a reference argument to elide the copy operation.
385 \throws senf::SystemException
388 void peer (Address & addr);
389 ///< Query remote address
390 /**< \see \ref peer() */
392 /** \brief Query local address
394 This member will return the address of the local socket in addressable protocols
395 (AddressingPolicy is not NoAddressingPolicy).
397 There are two Variants of this member, one will return the address by value, the other
398 takes a reference argument to elide the copy operation.
400 \throws senf::SystemException
403 void local (Address & addr);
404 ///< Query local address
405 /**< \see \ref local() */
409 ///////////////////////////////////////////////////////////////////////////
413 unsigned rcvbuf (); ///< Check size of receive buffer
414 /**< \returns size of receive buffer in bytes */
415 void rcvbuf (unsigned size);
416 ///< Set size of receive buffer
417 /**< \param[in] size size of receive buffer in bytes */
419 unsigned sndbuf (); ///< Check size of send buffer
420 /**< \returns size of send buffer in bytes */
421 void sndbuf (unsigned size);
422 ///< Set size of send buffer
423 /**< \param[in] size size of send buffer in bytes */
427 static ClientSocketHandle cast_static(FileHandle handle);
428 static ClientSocketHandle cast_dynamic(FileHandle handle);
430 // we need to override both since SocketHandle is *not* polymorphic
431 void state(SocketStateMap & map, unsigned lod=0);
432 std::string dumpState(unsigned lod=0);
435 ClientSocketHandle(FileHandle other, bool isChecked);
436 explicit ClientSocketHandle(std::auto_ptr<SocketProtocol> protocol,
440 unsigned available();
442 friend class senf::ServerSocketHandle<Policy>;
448 ///////////////////////////////hh.e////////////////////////////////////////
449 //#include "ClientSocketHandle.cci"
450 #include "ClientSocketHandle.ct"
451 #include "ClientSocketHandle.cti"
458 // c-file-style: "senf"
459 // indent-tabs-mode: nil
460 // ispell-local-dictionary: "american"
461 // compile-command: "scons -u test"
462 // comment-column: 40