asio 0.3.8rc3 Home | Reference | Tutorial | Examples | Design
Examples

services/stream_socket_service.hpp

Go to the documentation of this file.
00001 //
00002 // stream_socket_service.hpp
00003 // ~~~~~~~~~~~~~~~~~~~~~~~~~
00004 //
00005 // Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
00006 //
00007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
00008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
00009 //
00010 
00011 #ifndef SERVICES_STREAM_SOCKET_SERVICE_HPP
00012 #define SERVICES_STREAM_SOCKET_SERVICE_HPP
00013 
00014 #include <asio.hpp>
00015 #include <boost/noncopyable.hpp>
00016 #include <boost/lexical_cast.hpp>
00017 #include "logger.hpp"
00018 
00019 namespace services {
00020 
00022 template <typename Protocol>
00023 class stream_socket_service
00024   : public asio::io_service::service
00025 {
00026 private:
00028   typedef asio::stream_socket_service<Protocol> service_impl_type;
00029 
00030 public:
00032   static asio::io_service::id id;
00033 
00035   typedef Protocol protocol_type;
00036 
00038   typedef typename Protocol::endpoint endpoint_type;
00039 
00041   typedef typename service_impl_type::implementation_type implementation_type;
00042 
00044   typedef typename service_impl_type::native_type native_type;
00045 
00047   explicit stream_socket_service(asio::io_service& io_service)
00048     : asio::io_service::service(io_service),
00049       service_impl_(asio::use_service<service_impl_type>(io_service)),
00050       logger_(io_service, "stream_socket")
00051   {
00052   }
00053 
00055   void shutdown_service()
00056   {
00057   }
00058 
00060   void construct(implementation_type& impl)
00061   {
00062     service_impl_.construct(impl);
00063   }
00064 
00066   void destroy(implementation_type& impl)
00067   {
00068     service_impl_.destroy(impl);
00069   }
00070 
00072   asio::error_code open(implementation_type& impl,
00073       const protocol_type& protocol, asio::error_code& ec)
00074   {
00075     logger_.log("Opening new socket");
00076     return service_impl_.open(impl, protocol, ec);
00077   }
00078 
00080   asio::error_code assign(implementation_type& impl,
00081       const protocol_type& protocol, const native_type& native_socket,
00082       asio::error_code& ec)
00083   {
00084     logger_.log("Assigning from a native socket");
00085     return service_impl_.assign(impl, protocol, native_socket, ec);
00086   }
00087 
00089   bool is_open(const implementation_type& impl) const
00090   {
00091     logger_.log("Checking if socket is open");
00092     return service_impl_.is_open(impl);
00093   }
00094 
00096   asio::error_code close(implementation_type& impl,
00097       asio::error_code& ec)
00098   {
00099     logger_.log("Closing socket");
00100     return service_impl_.close(impl, ec);
00101   }
00102 
00104   bool at_mark(const implementation_type& impl,
00105       asio::error_code& ec) const
00106   {
00107     logger_.log("Checking if socket is at out-of-band data mark");
00108     return service_impl_.at_mark(impl, ec);
00109   }
00110 
00112   std::size_t available(const implementation_type& impl,
00113       asio::error_code& ec) const
00114   {
00115     logger_.log("Determining number of bytes available for reading");
00116     return service_impl_.available(impl, ec);
00117   }
00118 
00120   asio::error_code bind(implementation_type& impl,
00121       const endpoint_type& endpoint, asio::error_code& ec)
00122   {
00123     logger_.log("Binding socket");
00124     return service_impl_.bind(impl, endpoint, ec);
00125   }
00126 
00128   asio::error_code connect(implementation_type& impl,
00129       const endpoint_type& peer_endpoint, asio::error_code& ec)
00130   {
00131     logger_.log("Connecting socket to " +
00132         boost::lexical_cast<std::string>(peer_endpoint));
00133     return service_impl_.connect(impl, peer_endpoint, ec);
00134   }
00135 
00137   template <typename Handler>
00138   class connect_handler
00139   {
00140   public:
00141     connect_handler(Handler h, logger& l)
00142       : handler_(h),
00143         logger_(l)
00144     {
00145     }
00146 
00147     void operator()(const asio::error_code& e)
00148     {
00149       if (e)
00150       {
00151         std::string msg = "Asynchronous connect failed: ";
00152         msg += e.message();
00153         logger_.log(msg);
00154       }
00155       else
00156       {
00157         logger_.log("Asynchronous connect succeeded");
00158       }
00159 
00160       handler_(e);
00161     }
00162 
00163   private:
00164     Handler handler_;
00165     logger& logger_;
00166   };
00167 
00169   template <typename Handler>
00170   void async_connect(implementation_type& impl,
00171       const endpoint_type& peer_endpoint, Handler handler)
00172   {
00173     logger_.log("Starting asynchronous connect to " +
00174         boost::lexical_cast<std::string>(peer_endpoint));
00175     service_impl_.async_connect(impl, peer_endpoint, 
00176         connect_handler<Handler>(handler, logger_));
00177   }
00178 
00180   template <typename Option>
00181   asio::error_code set_option(implementation_type& impl,
00182       const Option& option, asio::error_code& ec)
00183   {
00184     logger_.log("Setting socket option");
00185     return service_impl_.set_option(impl, option, ec);
00186   }
00187 
00189   template <typename Option>
00190   asio::error_code get_option(const implementation_type& impl,
00191       Option& option, asio::error_code& ec) const
00192   {
00193     logger_.log("Getting socket option");
00194     return service_impl_.get_option(impl, option, ec);
00195   }
00196 
00198   template <typename IO_Control_Command>
00199   asio::error_code io_control(implementation_type& impl,
00200       IO_Control_Command& command, asio::error_code& ec)
00201   {
00202     logger_.log("Performing IO control command on socket");
00203     return service_impl_.io_control(impl, command, ec);
00204   }
00205 
00207   endpoint_type local_endpoint(const implementation_type& impl,
00208       asio::error_code& ec) const
00209   {
00210     logger_.log("Getting socket's local endpoint");
00211     return service_impl_.local_endpoint(impl, ec);
00212   }
00213 
00215   endpoint_type remote_endpoint(const implementation_type& impl,
00216       asio::error_code& ec) const
00217   {
00218     logger_.log("Getting socket's remote endpoint");
00219     return service_impl_.remote_endpoint(impl, ec);
00220   }
00221 
00223   asio::error_code shutdown(implementation_type& impl,
00224       asio::socket_base::shutdown_type what,
00225       asio::error_code& ec)
00226   {
00227     logger_.log("Shutting down socket");
00228     return service_impl_.shutdown(impl, what, ec);
00229   }
00230 
00232   template <typename Const_Buffers>
00233   std::size_t send(implementation_type& impl, const Const_Buffers& buffers,
00234       asio::socket_base::message_flags flags,
00235       asio::error_code& ec)
00236   {
00237     logger_.log("Sending data on socket");
00238     return service_impl_.send(impl, buffers, flags, ec);
00239   }
00240 
00242   template <typename Handler>
00243   class send_handler
00244   {
00245   public:
00246     send_handler(Handler h, logger& l)
00247       : handler_(h),
00248         logger_(l)
00249     {
00250     }
00251 
00252     void operator()(const asio::error_code& e,
00253         std::size_t bytes_transferred)
00254     {
00255       if (e)
00256       {
00257         std::string msg = "Asynchronous send failed: ";
00258         msg += e.message();
00259         logger_.log(msg);
00260       }
00261       else
00262       {
00263         logger_.log("Asynchronous send succeeded");
00264       }
00265 
00266       handler_(e, bytes_transferred);
00267     }
00268 
00269   private:
00270     Handler handler_;
00271     logger& logger_;
00272   };
00273 
00275   template <typename Const_Buffers, typename Handler>
00276   void async_send(implementation_type& impl, const Const_Buffers& buffers,
00277       asio::socket_base::message_flags flags, Handler handler)
00278   {
00279     logger_.log("Starting asynchronous send");
00280     service_impl_.async_send(impl, buffers, flags,
00281         send_handler<Handler>(handler, logger_));
00282   }
00283 
00285   template <typename Mutable_Buffers>
00286   std::size_t receive(implementation_type& impl,
00287       const Mutable_Buffers& buffers,
00288       asio::socket_base::message_flags flags,
00289       asio::error_code& ec)
00290   {
00291     logger_.log("Receiving data on socket");
00292     return service_impl_.receive(impl, buffers, flags, ec);
00293   }
00294 
00296   template <typename Handler>
00297   class receive_handler
00298   {
00299   public:
00300     receive_handler(Handler h, logger& l)
00301       : handler_(h),
00302         logger_(l)
00303     {
00304     }
00305 
00306     void operator()(const asio::error_code& e,
00307         std::size_t bytes_transferred)
00308     {
00309       if (e)
00310       {
00311         std::string msg = "Asynchronous receive failed: ";
00312         msg += e.message();
00313         logger_.log(msg);
00314       }
00315       else
00316       {
00317         logger_.log("Asynchronous receive succeeded");
00318       }
00319 
00320       handler_(e, bytes_transferred);
00321     }
00322 
00323   private:
00324     Handler handler_;
00325     logger& logger_;
00326   };
00327 
00329   template <typename Mutable_Buffers, typename Handler>
00330   void async_receive(implementation_type& impl, const Mutable_Buffers& buffers,
00331       asio::socket_base::message_flags flags, Handler handler)
00332   {
00333     logger_.log("Starting asynchronous receive");
00334     service_impl_.async_receive(impl, buffers, flags,
00335         receive_handler<Handler>(handler, logger_));
00336   }
00337 
00338 private:
00340   service_impl_type& service_impl_;
00341 
00343   mutable logger logger_;
00344 };
00345 
00346 template <typename Protocol>
00347 asio::io_service::id stream_socket_service<Protocol>::id;
00348 
00349 } // namespace services
00350 
00351 #endif // SERVICES_STREAM_SOCKET_SERVICE_HPP
asio 0.3.8rc3 Home | Reference | Tutorial | Examples | Design