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 template <class Policy>
91 class ClientSocketHandle
92 : public SocketHandle<Policy>
95 ///////////////////////////////////////////////////////////////////////////
98 /// Address type from the addressing policy
99 typedef typename Policy::AddressingPolicy::Address Address;
100 /// 'Best' type for passing address as parameter
101 /** Depending on the type of \c Address, this will be either <tt>Address</tt> or <tt>Address
103 href="http://www.boost.org/libs/utility/call_traits.htm">call_traits documentation in
104 the Boost.Utility library.</a>
106 typedef typename boost::call_traits<Address>::param_type AddressParam;
107 /// Corresponding server socket handle with the same policy
108 /** This class will probably only be usable, if the \c CommunicationPolicy is \c
109 ConnectedCommunicationPolicy and the \c AddressingPolicy is not \c
110 NoAddressingPolicy. */
111 typedef ServerSocketHandle<Policy> ServerSocketHandle;
113 ///////////////////////////////////////////////////////////////////////////
114 ///\name Structors and default members
117 // default default constructor
118 // default copy constructor
119 // default copy assignment
120 // default destructor
123 ClientSocketHandle();
125 // conversion constructors
127 template <class OtherPolicy>
128 ClientSocketHandle(ClientSocketHandle<OtherPolicy> other,
129 typename SocketHandle<Policy>::template IsCompatible<OtherPolicy>::type * = 0);
131 ClientSocketHandle(ClientSocketHandle<OtherPolicy> other);
135 template <class OtherPolicy>
136 typename SocketHandle<Policy>::template IsCompatible<OtherPolicy>::type const &
137 operator=(ClientSocketHandle<OtherPolicy> other);
139 template <class OtherPolicy>
140 OtherPolicy const & operator=(ClientSocketHandle<OtherPolicy> other);
144 ///////////////////////////////////////////////////////////////////////////
146 ///////////////////////////////////////////////////////////////////////////
147 ///\name Reading and Writing
150 /** \brief Read data from socket
152 If the sockets \c FramingPolicy is \c DatagramFramingPolicy, every read() command will
153 return a single datagram. If the sockets FramingPolicy is StreamFraming, the operation
154 will return as much data as possible from the socket buffer. However it cannot be
155 guaranteed, that the socket buffer will be empty after read() returns.
157 \attention If the space available for the data read is limited, the read will return no
158 more than that amount of data. For a datagram socket, a full datagram is still dequeued
159 from the socket buffer, the remainder of the datagram will be lost.
161 There are several variants of read which differ in how they return the read string.
163 If the further document doesn't tell something differently, on a blocking socket the
164 members will \e always return some data (as long as the socket has not been closed at
165 the other end) and will block, if no data is available now. If you do not want to block,
166 you \e must make the socket non-blocking (using FileHandle::blocking()).
168 \throws senf::SystemException
171 This variant will read up to \c limit bytes from the
172 socket and return them as a \c std::string object.
174 \param[in] limit Maximum number of bytes to read or 0 if unlimited.
177 \implementation The read() family of members will use standard POSIX \c read calls, not
180 std::string read (unsigned limit=0);
181 template <class ForwardWritableRange>
183 typename boost::range_iterator<ForwardWritableRange>::type
184 read (ForwardWritableRange const & range,
185 typename boost::disable_if< boost::is_convertible<ForwardWritableRange,unsigned> >::type * = 0);
187 typename boost::range_iterator<ForwardWritableRange>::type
188 read (ForwardWritableRange const & range);
189 ///< Read data into range
190 /**< Read data into the given range. At most
191 <tt>boost::size(range)</tt> characters are read. The
192 data read will start at the beginning of the
193 range. read returns a past-the-end iterator after the
194 last character read. This iterator will point to
195 somewhere within the input range.
196 \param[in,out] range Range to store data in
197 \returns past-the-end iterator pointer to after the
200 <a href="http://www.boost.org/libs/range/index.html">Boost.Range</a> */
203 template <class ForwardWritableRange>
204 typename boost::range_iterator<ForwardWritableRange>::type
205 read (ForwardWritableRange & range,
206 typename boost::disable_if< boost::is_convertible<ForwardWritableRange,unsigned> >::type * = 0);
208 template <class ForwardWritableRange>
209 typename boost::range_iterator<ForwardWritableRange>::type
210 read (ForwardWritableRange & range);
211 ///< Read data into range
212 /**< \see read(ForwardWritableRange const &) \n
214 <a href="http://www.boost.org/libs/range/index.html">Boost.Range</a> */
216 template <class Sequence>
217 void read (Sequence & container, unsigned limit);
218 ///< Read data into container
219 /**< The data read is written into the given container. Old
220 data in the container will be removed. For this to
221 work, the container must be a model of 'Sequence' as
222 defined in the STL documentation
223 \param[out] container Container to write data to
224 \param[in] limit Maximum number of characters to read
226 char * read (char * start, char * end);
227 ///< Read data into memory area
228 /**< This variant will read data into the memory area from
229 \a start to before \a end. This is guaranteed to be the
230 most efficient version of read().
231 \param[in] start address of buffer to store data at
232 \param[in] end address one past the end of the buffer
233 \returns pointer past the end of the data read
236 /** \brief Read data from unconnected socket returning address
238 The readfrom() group of member behaves like \ref read() but should only be available, if
239 the sockets \c CommunicationPolicy is \c UnconnectedCommunicationPolicy and the \c
240 AddressingPolicy is not \c NoAddressingPolicy. readfrom() will in addition to the data
241 return the address of the sender.
243 \throws senf::SystemException
246 This variant will return the data read and the address as a std::pair.
248 \returns \c std::pair of data read (a string) and the peers address
250 \implementation The readfrom() family of members will use \c recvfrom from the BSD
253 std::pair<std::string, Address>
254 readfrom (unsigned limit=0);
255 template <class ForwardWritableRange>
256 typename boost::range_iterator<ForwardWritableRange const>::type
257 readfrom (ForwardWritableRange const & range, Address & from);
258 ///< Read data into range
259 /**< Read data into the given range. At most
260 <tt>boost::size(range)</tt> characters are read. The
261 data read will start at the beginning of the
262 range. read returns a past-the-end iterator after the
263 last character read. This iterator will point to
264 somewhere within the input range.
265 \param[in,out] range Range to store data in
266 \param[out] from peers address from which the data was
268 \returns past-the-end iterator pointer to after the
270 \see \ref readfrom() \n
271 <a href="http://www.boost.org/libs/range/index.html">Boost.Range</a> */
272 template <class ForwardWritableRange>
273 typename boost::range_iterator<ForwardWritableRange>::type
274 readfrom (ForwardWritableRange & range, Address & from);
275 ///< Read data into range
276 /**< \see readfrom(ForwardWritableRange const&,Address&) \n
278 <a href="http://www.boost.org/libs/range/index.html">Boost.Range</a> */
279 template <class Sequence>
280 void readfrom (Sequence & container, Address & from, unsigned limit);
281 ///< Read data into container
282 /**< The data read is written into the given container. Old
283 data in the container will be removed. For this to
284 work, the container must be a model of 'Sequence' as
285 defined in the STL documentation
286 \param[out] container Container to write data to
287 \param[in] limit Maximum number of characters to read
288 \param[out] from peers address from which the data was
290 \see \ref readfrom() */
291 char * readfrom (char * start, char * end, Address & from);
292 ///< Read data into memory buffer
293 /**< This variant will read data into the memory area from
294 \a start to before \a end. This is guaranteed to be the
295 most efficient version of readfrom().
296 \param[in] start address of buffer to store data at
297 \param[in] end address one past the end of the buffer
298 \param[out] from peers address from which the data was
300 \returns pointer past the end of the data read
304 /** \brief Write data to socket
306 The write() family of members will write out the data to the socket. If the sockets \c
307 FramingPolicy is \c DatagramFramingPolicy, every write() call will result in one
310 A single write call might depending on the circumstances write only part of the data.
312 There are two variants of this member
314 \throws senf::SystemException
317 This variant will write out the range \c data.
319 \param[in] range Data to write
320 \returns past-the-end iterator after last element written
321 \implementation The write() family of members will use POSIX \c write calls, not \c
324 template <class ForwardReadableRange>
325 typename boost::range_const_iterator<ForwardReadableRange const>::type
326 write (ForwardReadableRange const & range);
327 char const * write (char const * start, char const * end);
328 ///< Write data to socket from memory buffer
329 /**< \param[in] start beginning of area to write
330 \param[in] end past-the-end pointer to area to write
331 \returns past-the-end pointer after last byte written
333 <a href="http://www.boost.org/libs/range/index.html">Boost.Range</a> */
335 /** \brief Write data to unconnected socket
337 This member behaves like write() but should only be available, if the sockets \c
338 CommunicationPolicy is \c UnconnectedCommunicationPolicy and the \c AddressingPolicy is
339 not \c NoAddressingPolicy. The writeto() family of members takes the target address as
340 an additional argument.
342 There are two variants of this member.
344 \throw senf::SystemException
347 This variant will send the range \c range to peer \c addr.
349 \param[in] addr Address of peer to send data to
350 \param[in] range data to send
351 \returns Number of bytes written
353 template <class ForwardReadableRange>
354 typename boost::range_const_iterator<ForwardReadableRange const>::type
355 writeto (AddressParam addr, ForwardReadableRange const & range);
356 char const * writeto (AddressParam addr, char const * start, char const * end);
357 ///< Write data from memory buffer to unconnected socket
358 /**< \param[in] addr Address of peer to send data to
359 \param[in] start address of buffer to write
360 \param[in] end past-the-end pointer after data to write
361 \returns past-the-end iterator after last byte written
362 \see \ref writeto() \n
363 <a href="http://www.boost.org/libs/range/index.html">Boost.Range</a> */
365 ///////////////////////////////////////////////////////////////////////////
369 /** \brief Connect to remote peer
371 This member will establish a connection for addressable connection-oriented protocols
372 (that is, the CommunicationPolicy is ConnectedCommunicationPolicy and the
373 AddressingPolicy is not NoAddressingPolicy).
375 \param[in] addr Address to connect to
377 \throws senf::SystemException
379 void connect (AddressParam addr);
381 /** \brief Set local address
383 For addressable protocols (AddressingPolicy is not NoAddressingPolicy), bind() will set
384 the local address of the socket.
386 \param[in] addr Local socket address to asign
388 \throws senf::SystemException
390 void bind (AddressParam addr);
392 /** \brief Query remote address
394 This member will return the address of the communication partner in addressable
395 connection-oriented protocols (that is, the CommunicationPolicy is
396 ConnectedCommunicationPolicy and the AddressingPolicy is not NoAddressingPolicy).
398 There are two Variants of this member, one will return the address by value, the other
399 takes a reference argument to elide the copy operation.
401 \throws senf::SystemException
404 void peer (Address & addr);
405 ///< Query remote address
406 /**< \see \ref peer() */
408 /** \brief Query local address
410 This member will return the address of the local socket in addressable protocols
411 (AddressingPolicy is not NoAddressingPolicy).
413 There are two Variants of this member, one will return the address by value, the other
414 takes a reference argument to elide the copy operation.
416 \throws senf::SystemException
419 void local (Address & addr);
420 ///< Query local address
421 /**< \see \ref local() */
425 ///////////////////////////////////////////////////////////////////////////
429 unsigned rcvbuf (); ///< Check size of receive buffer
430 /**< \returns size of receive buffer in bytes */
431 void rcvbuf (unsigned size);
432 ///< Set size of receive buffer
433 /**< \param[in] size size of receive buffer in bytes */
435 unsigned sndbuf (); ///< Check size of send buffer
436 /**< \returns size of send buffer in bytes */
437 void sndbuf (unsigned size);
438 ///< Set size of send buffer
439 /**< \param[in] size size of send buffer in bytes */
443 static ClientSocketHandle cast_static(FileHandle handle);
444 static ClientSocketHandle cast_dynamic(FileHandle handle);
446 // we need to override both since SocketHandle is *not* polymorphic
447 void state(SocketStateMap & map, unsigned lod=0);
448 std::string dumpState(unsigned lod=0);
451 ClientSocketHandle(FileHandle other, bool isChecked);
452 explicit ClientSocketHandle(std::auto_ptr<SocketProtocol> protocol,
456 unsigned available();
458 friend class senf::ServerSocketHandle<Policy>;
464 ///////////////////////////////hh.e////////////////////////////////////////
465 //#include "ClientSocketHandle.cci"
466 #include "ClientSocketHandle.ct"
467 #include "ClientSocketHandle.cti"
474 // c-file-style: "senf"
475 // indent-tabs-mode: nil
476 // ispell-local-dictionary: "american"
477 // compile-command: "scons -u test"
478 // comment-column: 40