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 "SocketHandle.hh"
35 //#include "ClientSocketHandle.mpp"
36 ///////////////////////////////hh.p////////////////////////////////////////
40 /// \addtogroup handle_group
43 template <class Policy> class ServerSocketHandle;
45 /** \brief Generic SocketHandle with client interface
47 This class provides the client side policy interface of the socket
48 abstraction. ClientSocketHandle defines the complete policy interface. It does not implement
49 any functionality itself however. All calls are forward to the following policy classes:
52 <tr><th>ClientSocketHandle member</th> <th>Policy member</th></tr>
53 <tr><td>read()</td> <td>ReadPolicy::read (\ref senf::ReadPolicyBase)</td></tr>
54 <tr><td>readfrom()</td> <td>ReadPolicy::readfrom (\ref senf::ReadPolicyBase)</td></tr>
55 <tr><td>write()</td> <td>WritePolicy::write (\ref senf::WritePolicyBase)</td></tr>
56 <tr><td>writeto()</td> <td>WritePolicy::writeto (\ref senf::WritePolicyBase)</td></tr>
57 <tr><td>connect()</td> <td>AddressingPolicy::connect (\ref senf::AddressingPolicyBase)</td></tr>
58 <tr><td>bind()</td> <td>AddressingPolicy::bind (\ref senf::AddressingPolicyBase)</td></tr>
59 <tr><td>peer()</td> <td>AddressingPolicy::peer (\ref senf::AddressingPolicyBase)</td></tr>
60 <tr><td>local()</td> <td>AddressingPolicy::local (\ref senf::AddressingPolicyBase)</td></tr>
61 <tr><td>rcvbuf()</td> <td>BufferingPolicy::sndbuf (\ref senf::BufferingPolicyBase)</td></tr>
62 <tr><td>sndbuf()</td> <td>BufferingPolicy::rcvbuf (\ref senf::BufferingPolicyBase)</td></tr>
65 It is important to note, that not all members are always accessible. Which are depends on
66 the \c Policy template argument. If any of the policy axis is left unspecified the
67 corresponding members will not be callable (you will get a compile time error). Even if
68 every policy axis is defined, some members might (and will) not exist if they are
69 meaningless for the protocol of the socket. This depends on the exact policy.
71 To find out, which members are available, you have to check the documentation of the policy
72 classes. You can also find a summary of all members available in the leaf protocol class
75 \todo Move all not template-parameter dependent code into a non-template base class
77 \idea Give SocketHandle (and therefore ClientSocketHandle and ServerSocketHandle) a \c
78 protocol() template member and an additional template arg \c Policies. This arg should be a
79 typelist of Poclicy classes which can be accessed. You use protocol<ProtocolClass>() to
80 access a protocol class. \c Policies can of course be underspecified or even empty.
82 \see \ref policy_group \n
85 template <class Policy>
86 class ClientSocketHandle
87 : public SocketHandle<Policy>
90 ///////////////////////////////////////////////////////////////////////////
93 /// Address type from the addressing policy
94 typedef typename Policy::AddressingPolicy::Address Address;
95 /// 'Best' type for passing address as parameter
96 /** Depending on the type of \c Address, this will be either <tt>Address</tt> or <tt>Address
98 href="http://www.boost.org/libs/utility/call_traits.htm">call_traits documentation in
99 the Boost.Utility library.</a>
101 typedef typename boost::call_traits<Address>::param_type AddressParam;
102 /// Corresponding server socket handle with the same policy
103 /** This class will probably only be usable, if the \c CommunicationPolicy is \c
104 ConnectedCommunicationPolicy and the \c AddressingPolicy is not \c
105 NoAddressingPolicy. */
106 typedef ServerSocketHandle<Policy> ServerSocketHandle;
108 ///////////////////////////////////////////////////////////////////////////
109 ///\name Structors and default members
112 // default default constructor
113 // default copy constructor
114 // default copy assignment
115 // default destructor
118 ClientSocketHandle();
120 // conversion constructors
121 template <class OtherPolicy>
122 ClientSocketHandle(ClientSocketHandle<OtherPolicy> other,
123 typename SocketHandle<Policy>::template IsCompatible<OtherPolicy>::type * = 0);
125 template <class OtherPolicy>
126 typename SocketHandle<Policy>::template IsCompatible<OtherPolicy>::type const &
127 operator=(ClientSocketHandle<OtherPolicy> other);
130 ///////////////////////////////////////////////////////////////////////////
132 ///////////////////////////////////////////////////////////////////////////
133 ///\name Reading and Writing
136 /** \brief Read data from socket
138 If the sockets \c FramingPolicy is \c DatagramFramingPolicy, every read() command will
139 return a single datagram. If the sockets FramingPolicy is StreamFraming, the operation
140 will return as much data as possible from the socket buffer. However it cannot be
141 guaranteed, that the socket buffer will be empty after read() returns.
143 \attention If the space available for the data read is limited, the read will return no
144 more than that amount of data. For a datagram socket, a full datagram is still dequeued
145 from the socket buffer, the remainder of the datagram will be lost.
147 There are several variants of read which differ in how they return the read string.
149 If the further document doesn't tell something differently, on a blocking socket the
150 members will \e always return some data (as long as the socket has not been closed at
151 the other end) and will block, if no data is available now. If you do not want to block,
152 you \e must make the socket non-blocking (using FileHandle::blocking()).
154 \throws senf::SystemException
157 This variant will read up to \c limit bytes from the
158 socket and return them as a \c std::string object.
160 \param[in] limit Maximum number of bytes to read or 0 if unlimited.
163 \implementation The read() family of members will use standard POSIX \c read calls, not
166 std::string read (unsigned limit=0);
167 template <class ForwardWritableRange>
168 typename boost::range_iterator<ForwardWritableRange>::type
169 read (ForwardWritableRange const & range);
170 ///< Read data into range
171 /**< Read data into the given range. At most
172 <tt>boost::size(range)</tt> characters are read. The
173 data read will start at the beginning of the
174 range. read returns a past-the-end iterator after the
175 last character read. This iterator will point to
176 somewhere within the input range.
177 \param[in/out] range Range to store data in
178 \returns past-the-end iterator pointer to after the
181 <a href="http://www.boost.org/libs/range/index.html">Boost.Range</a> */
182 template <class ForwardWritableRange>
183 typename boost::range_iterator<ForwardWritableRange>::type
184 read (ForwardWritableRange & range);
185 ///< Read data into range
186 /**< \see read(ForwardWritableRange const &) \n
188 <a href="http://www.boost.org/libs/range/index.html">Boost.Range</a> */
189 template <class Sequence>
190 void read (Sequence & container, unsigned limit);
191 ///< Read data into container
192 /**< The data read is written into the given container. Old
193 data in the container will be removed. For this to
194 work, the container must be a model of 'Sequence' as
195 defined in the STL documentation
196 \param[out] container Container to write data to
197 \param[in] limit Maximum number of characters to read
199 char * read (char * start, char * end);
200 ///< Read data into memory area
201 /**< This variant will read data into the memory area from
202 \a start to before \a end. This is guaranteed to be the
203 most efficient version of read().
204 \param[in] start address of buffer to store data at
205 \param[in] end address one past the end of the buffer
206 \returns pointer past the end of the data read
209 /** \brief Read data from unconnected socket returning address
211 The readfrom() group of member behaves like \ref read() but should only be available, if
212 the sockets \c CommunicationPolicy is \c UnconnectedCommunicationPolicy and the \c
213 AddressingPolicy is not \c NoAddressingPolicy. readfrom() will in addition to the data
214 return the address of the sender.
216 \throws senf::SystemException
219 This variant will return the data read and the address as a std::pair.
221 \returns \c std::pair of data read (a string) and the peers address
223 \implementation The readfrom() family of members will use \c recvfrom from the BSD
226 std::pair<std::string, Address>
227 readfrom (unsigned limit=0);
228 template <class ForwardWritableRange>
229 typename boost::range_iterator<ForwardWritableRange const>::type
230 readfrom (ForwardWritableRange const & range, Address & from);
231 ///< Read data into range
232 /**< Read data into the given range. At most
233 <tt>boost::size(range)</tt> characters are read. The
234 data read will start at the beginning of the
235 range. read returns a past-the-end iterator after the
236 last character read. This iterator will point to
237 somewhere within the input range.
238 \param[in/out] range Range to store data in
239 \param[out] from peers address from which the data was
241 \returns past-the-end iterator pointer to after the
243 \see \ref readfrom() \n
244 <a href="http://www.boost.org/libs/range/index.html">Boost.Range</a> */
245 template <class ForwardWritableRange>
246 typename boost::range_iterator<ForwardWritableRange>::type
247 readfrom (ForwardWritableRange & range, Address & from);
248 ///< Read data into range
249 /**< \see readfrom(ForwardWritableRange const&,Address&) \n
251 <a href="http://www.boost.org/libs/range/index.html">Boost.Range</a> */
252 template <class Sequence>
253 void readfrom (Sequence & container, Address & from, unsigned limit);
254 ///< Read data into container
255 /**< The data read is written into the given container. Old
256 data in the container will be removed. For this to
257 work, the container must be a model of 'Sequence' as
258 defined in the STL documentation
259 \param[out] container Container to write data to
260 \param[in] limit Maximum number of characters to read
261 \param[out] from peers address from which the data was
263 \see \ref readfrom() */
264 char * readfrom (char * start, char * end, Address & from);
265 ///< Read data into memory buffer
266 /**< This variant will read data into the memory area at \c
267 buffer of size \c size. This is the most performant
268 version of readfrom().
269 \param[in] buffer address of buffer to store data at
270 \param[in] size size of buffer
271 \param[out] from peer address
272 \returns Number of bytes read
273 \see \ref readfrom() */
276 /** \brief Write data to socket
278 The write() family of members will write out the data to the socket. If the sockets \c
279 FramingPolicy is \c DatagramFramingPolicy, every write() call will result in one
282 A single write call might depending on the circumstances write only part of the data.
284 There are two variants of this member
286 \throws senf::SystemException
289 This variant will write out the range \c data.
291 \param[in] range Data to write
292 \returns past-the-end iterator after last element written
293 \implementation The write() family of members will use POSIX \c write calls, not \c
296 template <class ForwardReadableRange>
297 typename boost::range_const_iterator<ForwardReadableRange const>::type
298 write (ForwardReadableRange const & range);
299 char const * write (char const * start, char const * end);
300 ///< Write data to socket from memory buffer
301 /**< \param[in] start beginning of area to write
302 \param[in] end past-the-end pointer to area to write
303 \returns past-the-end pointer after last byte written
305 <a href="http://www.boost.org/libs/range/index.html">Boost.Range</a> */
307 /** \brief Write data to unconnected socket
309 This member behaves like write() but should only be available, if the sockets \c
310 CommunicationPolicy is \c UnconnectedCommunicationPolicy and the \c AddressingPolicy is
311 not \c NoAddressingPolicy. The writeto() family of members takes the target address as
312 an additional argument.
314 There are two variants of this member.
316 \throw senf::SystemException
319 This variant will send the range \c range to peer \c addr.
321 \param[in] addr Address of peer to send data to
322 \param[in] range data to send
323 \returns Number of bytes written
325 template <class ForwardReadableRange>
326 typename boost::range_const_iterator<ForwardReadableRange const>::type
327 writeto (AddressParam addr, ForwardReadableRange const & range);
328 char const * writeto (AddressParam addr, char const * start, char const * end);
329 ///< Write data from memory buffer to unconnected socket
330 /**< \param[in] addr Address of peer to send data to
331 \param[in] start address of buffer to write
332 \param[in] end past-the-end pointer after data to write
333 \returns past-the-end iterator after last byte written
334 \see \ref writeto() \n
335 <a href="http://www.boost.org/libs/range/index.html">Boost.Range</a> */
337 ///////////////////////////////////////////////////////////////////////////
341 /** \brief Connect to remote peer
343 This member will establish a connection for addressable connection-oriented protocols
344 (that is, the CommunicationPolicy is ConnectedCommunicationPolicy and the
345 AddressingPolicy is not NoAddressingPolicy).
347 \param[in] addr Address to connect to
349 \throws senf::SystemException
351 void connect (AddressParam addr);
353 /** \brief Set local address
355 For addressable protocols (AddressingPolicy is not NoAddressingPolicy), bind() will set
356 the local address of the socket.
358 \param[in] addr Local socket address to asign
360 \throws senf::SystemException
362 void bind (AddressParam addr);
364 /** \brief Query remote address
366 This member will return the address of the communication partner in addressable
367 connection-oriented protocols (that is, the CommunicationPolicy is
368 ConnectedCommunicationPolicy and the AddressingPolicy is not NoAddressingPolicy).
370 There are two Variants of this member, one will return the address by value, the other
371 takes a reference argument to elide the copy operation.
373 \throws senf::SystemException
376 void peer (Address & addr);
377 ///< Query remote address
378 /**< \see \ref peer() */
380 /** \brief Query local address
382 This member will return the address of the local socket in addressable protocols
383 (AddressingPolicy is not NoAddressingPolicy).
385 There are two Variants of this member, one will return the address by value, the other
386 takes a reference argument to elide the copy operation.
388 \throws senf::SystemException
391 void local (Address & addr);
392 ///< Query local address
393 /**< \see \ref local() */
397 ///////////////////////////////////////////////////////////////////////////
401 unsigned rcvbuf (); ///< Check size of receive buffer
402 /**< \returns size of receive buffer in bytes */
403 void rcvbuf (unsigned size);
404 ///< Set size of receive buffer
405 /**< \param[in] size size of receive buffer in bytes */
407 unsigned sndbuf (); ///< Check size of send buffer
408 /**< \returns size of send buffer in bytes */
409 void sndbuf (unsigned size);
410 ///< Set size of send buffer
411 /**< \param[in] size size of send buffer in bytes */
415 static ClientSocketHandle cast_static(FileHandle handle);
416 static ClientSocketHandle cast_dynamic(FileHandle handle);
418 // we need to override both since SocketHandle is *not* polymorphic
419 void state(SocketStateMap & map, unsigned lod=0);
420 std::string dumpState(unsigned lod=0);
423 ClientSocketHandle(FileHandle other, bool isChecked);
424 explicit ClientSocketHandle(std::auto_ptr<SocketProtocol> protocol,
428 unsigned available();
430 friend class senf::ServerSocketHandle<Policy>;
436 ///////////////////////////////hh.e////////////////////////////////////////
437 //#include "ClientSocketHandle.cci"
438 #include "ClientSocketHandle.ct"
439 #include "ClientSocketHandle.cti"
446 // c-file-style: "senf"
447 // indent-tabs-mode: nil
448 // ispell-local-dictionary: "american"