4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief ClientSocketHandle public header
32 #ifndef HH_SENF_Socket_ClientSocketHandle_
33 #define HH_SENF_Socket_ClientSocketHandle_ 1
36 #include <boost/call_traits.hpp>
37 #include <boost/range.hpp>
38 #include <boost/utility.hpp>
39 #include <boost/type_traits.hpp>
40 #include "SocketHandle.hh"
42 //#include "ClientSocketHandle.mpp"
43 //-/////////////////////////////////////////////////////////////////////////////////////////////////
47 /// \addtogroup handle_group
50 template <class SPolicy> class ServerSocketHandle;
52 /** \brief Generic SocketHandle with client interface
54 This class provides the client side policy interface of the socket
55 abstraction. ClientSocketHandle defines the complete policy interface. It does not implement
56 any functionality itself however. The following table shows, to which policy members each
57 group of ClientSocketHandle members is forwarded. The last column shows, on which other
58 policies this member-group depends <em>in the default policy classes</em>. If you define
59 your own policy classes, the dependencies are up to you.
62 <tr><th>ClientSocketHandle member</th> <th>Policy member</th> <th>Other policies</th></tr>
63 <tr><td>read()</td> <td>ReadPolicy::read (\ref senf::ReadPolicyBase)</td> <td></td></tr>
64 <tr><td>readfrom()</td> <td>ReadPolicy::readfrom (\ref senf::ReadPolicyBase)</td> <td>UnconnectedCommunicationPolicy</td></tr>
65 <tr><td>write()</td> <td>WritePolicy::write (\ref senf::WritePolicyBase)</td> <td>ConnectedCommunicationPolicy</td></tr>
66 <tr><td>writeto()</td> <td>WritePolicy::writeto (\ref senf::WritePolicyBase)</td> <td>UnconnectedCommunicationPolicy</td></tr>
67 <tr><td>connect()</td> <td>AddressingPolicy::connect (\ref senf::AddressingPolicyBase)</td> <td></td></tr>
68 <tr><td>bind()</td> <td>AddressingPolicy::bind (\ref senf::AddressingPolicyBase)</td> <td></td></tr>
69 <tr><td>peer()</td> <td>AddressingPolicy::peer (\ref senf::AddressingPolicyBase)</td> <td></td></tr>
70 <tr><td>local()</td> <td>AddressingPolicy::local (\ref senf::AddressingPolicyBase)</td> <td></td></tr>
73 It is important to note, that not all members are always accessible. Which are depends on
74 the \c Policy template argument. If any of the policy axis is left unspecified the
75 corresponding members will not be callable (you will get a compile time error). Even if
76 every policy axis is defined, some members might (and will) not exist if they are
77 meaningless for the protocol of the socket. This depends on the exact policy.
79 To find out, which members are available, you have to check the documentation of the policy
80 classes. You can also find a summary of all members available in the leaf protocol class
83 \todo Move all not template-parameter dependent code into a non-template base class
85 \idea Give SocketHandle (and therefore ClientSocketHandle and ServerSocketHandle) a \c
86 protocol() template member and an additional template arg \c Policies. This arg should be a
87 typelist of policy classes which can be accessed. You use protocol<ProtocolClass>() to
88 access a protocol class. \c Policies can of course be underspecified or even empty.
90 \see \ref policy_group \n
93 template <class SPolicy>
94 class ClientSocketHandle
95 : public SocketHandle<SPolicy>
98 //-////////////////////////////////////////////////////////////////////////
101 /// Address type from the addressing policy
102 typedef typename SPolicy::AddressingPolicy::Address Address;
103 /// 'Best' type for passing address as parameter
104 /** Depending on the type of \c Address, this will be either <tt>Address</tt> or <tt>Address
106 href="http://www.boost.org/doc/libs/release/libs/utility/call_traits.htm">call_traits documentation in
107 the Boost.Utility library.</a>
109 typedef typename boost::call_traits<Address>::param_type AddressParam;
110 /// Corresponding server socket handle with the same policy
111 /** This class will probably only be usable, if the \c CommunicationPolicy is \c
112 ConnectedCommunicationPolicy and the \c AddressingPolicy is not \c
113 NoAddressingPolicy. */
114 typedef ServerSocketHandle<SPolicy> ServerHandle;
116 //-////////////////////////////////////////////////////////////////////////
117 ///\name Structors and default members
120 // default default constructor
121 // default copy constructor
122 // default copy assignment
123 // default destructor
126 ClientSocketHandle();
128 // conversion constructors
130 template <class OtherPolicy>
131 ClientSocketHandle(ClientSocketHandle<OtherPolicy> other,
132 typename SocketHandle<SPolicy>::template IsCompatible<OtherPolicy>::type * = 0);
134 ClientSocketHandle(ClientSocketHandle<OtherPolicy> other);
138 template <class OtherPolicy>
139 typename SocketHandle<SPolicy>::template IsCompatible<OtherPolicy>::type const &
140 operator=(ClientSocketHandle<OtherPolicy> other);
142 template <class OtherPolicy>
143 ClientSocketHandle<OtherPolicy> const & operator=(ClientSocketHandle<OtherPolicy> other);
147 //-////////////////////////////////////////////////////////////////////////
149 //-////////////////////////////////////////////////////////////////////////
150 ///\name Reading and Writing
153 /** \brief Read data from socket
155 If the sockets \c FramingPolicy is \c DatagramFramingPolicy, every read() command will
156 return a single datagram. If the sockets FramingPolicy is StreamFraming, the operation
157 will return as much data as possible from the socket buffer. However it cannot be
158 guaranteed, that the socket buffer will be empty after read() returns.
160 \attention If the space available for the data read is limited, the read will return no
161 more than that amount of data. For a datagram socket, a full datagram is still dequeued
162 from the socket buffer, the remainder of the datagram will be lost.
164 There are several variants of read which differ in how they return the read string.
166 If the further document doesn't tell something differently, on a blocking socket the
167 members will \e always return some data (as long as the socket has not been closed at
168 the other end) and will block, if no data is available now. If you do not want to block,
169 you \e must make the socket non-blocking (using FileHandle::blocking()).
171 \throws senf::SystemException
174 This variant will read up to \c limit bytes from the
175 socket and return them as a \c std::string object.
177 \param[in] limit Maximum number of bytes to read or 0 if unlimited.
180 \implementation The read() family of members will use standard POSIX \c read calls, not
183 std::string read (unsigned limit=0);
186 template <class ForwardWritableRange>
187 typename boost::disable_if< boost::is_convertible<ForwardWritableRange,unsigned>,
188 typename boost::range_iterator<ForwardWritableRange>::type>::type
189 read(ForwardWritableRange const & range);
191 template <class ForwardWritableRange>
192 typename boost::range_iterator<ForwardWritableRange>::type
193 read (ForwardWritableRange const & range);
194 ///< Read data into range
195 /**< Read data into the given range. At most
196 <tt>boost::size(range)</tt> characters are read. The
197 data read will start at the beginning of the
198 range. read returns a past-the-end iterator after the
199 last character read. This iterator will point to
200 somewhere within the input range.
201 \param[in,out] range Range to store data in
202 \returns past-the-end iterator pointer to after the
205 <a href="http://www.boost.org/doc/libs/release/libs/range/index.html">Boost.Range</a> */
208 template <class ForwardWritableRange>
209 typename boost::disable_if< boost::is_convertible<ForwardWritableRange,unsigned>,
210 typename boost::range_iterator<ForwardWritableRange>::type>::type
211 read(ForwardWritableRange & range);
213 template <class ForwardWritableRange>
214 typename boost::range_iterator<ForwardWritableRange>::type
215 read (ForwardWritableRange & range);
216 ///< Read data into range
217 /**< \see read(ForwardWritableRange const &) \n
219 <a href="http://www.boost.org/doc/libs/release/libs/range/index.html">Boost.Range</a> */
221 template <class Sequence>
222 void read (Sequence & container, unsigned limit);
223 ///< Read data into container
224 /**< The data read is written into the given container. Old
225 data in the container will be removed. For this to
226 work, the container must be a model of 'Sequence' as
227 defined in the STL documentation
228 \param[out] container Container to write data to
229 \param[in] limit Maximum number of characters to read
231 char * read (char * start, char * end);
232 ///< Read data into memory area
233 /**< This variant will read data into the memory area from
234 \a start to before \a end. This is guaranteed to be the
235 most efficient version of read().
236 \param[in] start address of buffer to store data at
237 \param[in] end address one past the end of the buffer
238 \returns pointer past the end of the data read
241 /** \brief Read data from unconnected socket returning address
243 The readfrom() group of member behaves like \ref read() but should only be available, if
244 the sockets \c CommunicationPolicy is \c UnconnectedCommunicationPolicy and the \c
245 AddressingPolicy is not \c NoAddressingPolicy. readfrom() will in addition to the data
246 return the address of the sender.
248 \throws senf::SystemException
251 This variant will return the data read and the address as a std::pair.
253 \returns \c std::pair of data read (a string) and the peers address
255 \implementation The readfrom() family of members will use \c recvfrom from the BSD
258 std::pair<std::string, Address>
259 readfrom (unsigned limit=0);
260 template <class ForwardWritableRange>
261 typename boost::range_iterator<ForwardWritableRange const>::type
262 readfrom (ForwardWritableRange const & range, Address & from);
263 ///< Read data into range
264 /**< Read data into the given range. At most
265 <tt>boost::size(range)</tt> characters are read. The
266 data read will start at the beginning of the
267 range. read returns a past-the-end iterator after the
268 last character read. This iterator will point to
269 somewhere within the input range.
270 \param[in,out] range Range to store data in
271 \param[out] from peers address from which the data was
273 \returns past-the-end iterator pointer to after the
275 \see \ref readfrom() \n
276 <a href="http://www.boost.org/doc/libs/release/libs/range/index.html">Boost.Range</a> */
277 template <class ForwardWritableRange>
278 typename boost::range_iterator<ForwardWritableRange>::type
279 readfrom (ForwardWritableRange & range, Address & from);
280 ///< Read data into range
281 /**< \see readfrom(ForwardWritableRange const&,Address&) \n
283 <a href="http://www.boost.org/doc/libs/release/libs/range/index.html">Boost.Range</a> */
284 template <class Sequence>
285 void readfrom (Sequence & container, Address & from, unsigned limit);
286 ///< Read data into container
287 /**< The data read is written into the given container. Old
288 data in the container will be removed. For this to
289 work, the container must be a model of 'Sequence' as
290 defined in the STL documentation
291 \param[out] container Container to write data to
292 \param[in] limit Maximum number of characters to read
293 \param[out] from peers address from which the data was
295 \see \ref readfrom() */
296 char * readfrom (char * start, char * end, Address & from);
297 ///< Read data into memory buffer
298 /**< This variant will read data into the memory area from
299 \a start to before \a end. This is guaranteed to be the
300 most efficient version of readfrom().
301 \param[in] start address of buffer to store data at
302 \param[in] end address one past the end of the buffer
303 \param[out] from peers address from which the data was
305 \returns pointer past the end of the data read
309 /** \brief Write data to socket
311 The write() family of members will write out the data to the socket. If the sockets \c
312 FramingPolicy is \c DatagramFramingPolicy, every write() call will result in one
315 A single write call might depending on the circumstances write only part of the data.
317 There are two variants of this member
319 \throws senf::SystemException
322 This variant will write out the range \c data.
324 \param[in] range Data to write
325 \returns past-the-end iterator after last element written
326 \implementation The write() family of members will use POSIX \c write calls, not \c
329 template <class ForwardReadableRange>
330 typename boost::range_const_iterator<ForwardReadableRange const>::type
331 write (ForwardReadableRange const & range);
332 char const * write (char const * start, char const * end);
333 ///< Write data to socket from memory buffer
334 /**< \param[in] start beginning of area to write
335 \param[in] end past-the-end pointer to area to write
336 \returns past-the-end pointer after last byte written
338 <a href="http://www.boost.org/doc/libs/release/libs/range/index.html">Boost.Range</a> */
340 /** \brief Write data to unconnected socket
342 This member behaves like write() but should only be available, if the sockets \c
343 CommunicationPolicy is \c UnconnectedCommunicationPolicy and the \c AddressingPolicy is
344 not \c NoAddressingPolicy. The writeto() family of members takes the target address as
345 an additional argument.
347 There are two variants of this member.
349 \throw senf::SystemException
352 This variant will send the range \c range to peer \c addr.
354 \param[in] addr Address of peer to send data to
355 \param[in] range data to send
356 \returns Number of bytes written
358 template <class ForwardReadableRange>
359 typename boost::range_const_iterator<ForwardReadableRange const>::type
360 writeto (AddressParam addr, ForwardReadableRange const & range);
361 char const * writeto (AddressParam addr, char const * start, char const * end);
362 ///< Write data from memory buffer to unconnected socket
363 /**< \param[in] addr Address of peer to send data to
364 \param[in] start address of buffer to write
365 \param[in] end past-the-end pointer after data to write
366 \returns past-the-end iterator after last byte written
367 \see \ref writeto() \n
368 <a href="http://www.boost.org/doc/libs/release/libs/range/index.html">Boost.Range</a> */
370 //-////////////////////////////////////////////////////////////////////////
374 /** \brief Connect to remote peer
376 This member will establish a connection for addressable connection-oriented protocols
377 (that is, the CommunicationPolicy is ConnectedCommunicationPolicy and the
378 AddressingPolicy is not NoAddressingPolicy).
380 \param[in] addr Address to connect to
382 \throws senf::SystemException
384 void connect (AddressParam addr) const;
386 /** \brief Set local address
388 For addressable protocols (AddressingPolicy is not NoAddressingPolicy), bind() will set
389 the local address of the socket.
391 \param[in] addr Local socket address to assign
393 \throws senf::SystemException
395 void bind (AddressParam addr) const;
397 /** \brief Query remote address
399 This member will return the address of the communication partner in addressable
400 connection-oriented protocols (that is, the CommunicationPolicy is
401 ConnectedCommunicationPolicy and the AddressingPolicy is not NoAddressingPolicy).
403 There are two Variants of this member, one will return the address by value, the other
404 takes a reference argument to elide the copy operation.
406 \throws senf::SystemException
408 Address peer () const;
409 void peer (Address & addr) const;
410 ///< Query remote address
411 /**< \see \ref peer() */
413 /** \brief Query local address
415 This member will return the address of the local socket in addressable protocols
416 (AddressingPolicy is not NoAddressingPolicy).
418 There are two Variants of this member, one will return the address by value, the other
419 takes a reference argument to elide the copy operation.
421 \throws senf::SystemException
423 Address local () const;
424 void local (Address & addr) const;
425 ///< Query local address
426 /**< \see \ref local() */
430 static ClientSocketHandle cast_static(FileHandle handle);
431 static ClientSocketHandle cast_dynamic(FileHandle handle);
433 // we need to override both since SocketHandle is *not* polymorphic
434 void state(SocketStateMap & map, unsigned lod=0);
435 std::string dumpState(unsigned lod=0);
437 unsigned available();
440 ClientSocketHandle(FileHandle other, bool isChecked);
441 explicit ClientSocketHandle(std::auto_ptr<SocketBody> body);
444 friend class senf::ServerSocketHandle<SPolicy>;
450 //-/////////////////////////////////////////////////////////////////////////////////////////////////
451 //#include "ClientSocketHandle.cci"
452 #include "ClientSocketHandle.ct"
453 #include "ClientSocketHandle.cti"
460 // c-file-style: "senf"
461 // indent-tabs-mode: nil
462 // ispell-local-dictionary: "american"
463 // compile-command: "scons -u test"
464 // comment-column: 40