asio 0.3.7 Home | Reference | Tutorial | Examples | Design
Examples

services/stream_socket_service.hpp

Go to the documentation of this file.
00001 #ifndef SERVICES_STREAM_SOCKET_SERVICE_HPP
00002 #define SERVICES_STREAM_SOCKET_SERVICE_HPP
00003 
00004 #include <asio.hpp>
00005 #include <boost/noncopyable.hpp>
00006 #include <boost/lexical_cast.hpp>
00007 #include "logger.hpp"
00008 
00009 namespace services {
00010 
00012 template <typename Protocol>
00013 class stream_socket_service
00014   : public asio::io_service::service
00015 {
00016 private:
00018   typedef asio::stream_socket_service<Protocol> service_impl_type;
00019 
00020 public:
00022   typedef Protocol protocol_type;
00023 
00025   typedef typename Protocol::endpoint endpoint_type;
00026 
00028   typedef typename service_impl_type::implementation_type implementation_type;
00029 
00031   typedef typename service_impl_type::native_type native_type;
00032 
00034   explicit stream_socket_service(asio::io_service& io_service)
00035     : asio::io_service::service(io_service),
00036       service_impl_(asio::use_service<service_impl_type>(io_service)),
00037       logger_(io_service, "stream_socket")
00038   {
00039   }
00040 
00042   void shutdown_service()
00043   {
00044   }
00045 
00047   void construct(implementation_type& impl)
00048   {
00049     service_impl_.construct(impl);
00050   }
00051 
00053   void destroy(implementation_type& impl)
00054   {
00055     service_impl_.destroy(impl);
00056   }
00057 
00059   template <typename Error_Handler>
00060   void open(implementation_type& impl, const protocol_type& protocol,
00061       Error_Handler error_handler)
00062   {
00063     logger_.log("Opening new socket");
00064     service_impl_.open(impl, protocol, error_handler);
00065   }
00066 
00068   template <typename Error_Handler>
00069   void open(implementation_type& impl, const native_type& native_socket,
00070       Error_Handler error_handler)
00071   {
00072     logger_.log("Opening native socket");
00073     service_impl_.open(impl, native_socket, error_handler);
00074   }
00075 
00077   template <typename Error_Handler>
00078   void close(implementation_type& impl, Error_Handler error_handler)
00079   {
00080     logger_.log("Closing socket");
00081     service_impl_.close(impl, error_handler);
00082   }
00083 
00085   template <typename Error_Handler>
00086   void bind(implementation_type& impl, const endpoint_type& endpoint,
00087       Error_Handler error_handler)
00088   {
00089     logger_.log("Binding socket");
00090     service_impl_.bind(impl, endpoint, error_handler);
00091   }
00092 
00094   template <typename Error_Handler>
00095   void connect(implementation_type& impl, const endpoint_type& peer_endpoint,
00096       Error_Handler error_handler)
00097   {
00098     logger_.log("Connecting socket to " +
00099         boost::lexical_cast<std::string>(peer_endpoint));
00100     service_impl_.connect(impl, peer_endpoint, error_handler);
00101   }
00102 
00104   template <typename Handler>
00105   class connect_handler
00106   {
00107   public:
00108     connect_handler(Handler h, logger& l)
00109       : handler_(h),
00110         logger_(l)
00111     {
00112     }
00113 
00114     void operator()(const asio::error& e)
00115     {
00116       if (e)
00117       {
00118         std::string msg = "Asynchronous connect failed: ";
00119         msg += e.what();
00120         logger_.log(msg);
00121       }
00122       else
00123       {
00124         logger_.log("Asynchronous connect succeeded");
00125       }
00126 
00127       handler_(e);
00128     }
00129 
00130   private:
00131     Handler handler_;
00132     logger& logger_;
00133   };
00134 
00136   template <typename Handler>
00137   void async_connect(implementation_type& impl,
00138       const endpoint_type& peer_endpoint, Handler handler)
00139   {
00140     logger_.log("Starting asynchronous connect to " +
00141         boost::lexical_cast<std::string>(peer_endpoint));
00142     service_impl_.async_connect(impl, peer_endpoint, 
00143         connect_handler<Handler>(handler, logger_));
00144   }
00145 
00147   template <typename Option, typename Error_Handler>
00148   void set_option(implementation_type& impl, const Option& option,
00149       Error_Handler error_handler)
00150   {
00151     logger_.log("Setting socket option");
00152     service_impl_.set_option(impl, option, error_handler);
00153   }
00154 
00156   template <typename Option, typename Error_Handler>
00157   void get_option(const implementation_type& impl, Option& option,
00158       Error_Handler error_handler) const
00159   {
00160     logger_.log("Getting socket option");
00161     service_impl_.get_option(impl, option, error_handler);
00162   }
00163 
00165   template <typename IO_Control_Command, typename Error_Handler>
00166   void io_control(implementation_type& impl, IO_Control_Command& command,
00167       Error_Handler error_handler)
00168   {
00169     logger_.log("Performing IO control command on socket");
00170     service_impl_.io_control(impl, command, error_handler);
00171   }
00172 
00174   template <typename Error_Handler>
00175   void local_endpoint(const implementation_type& impl,
00176       Error_Handler error_handler) const
00177   {
00178     logger_.log("Getting socket's local endpoint");
00179     return service_impl_.local_endpoint(impl, error_handler);
00180   }
00181 
00183   template <typename Error_Handler>
00184   endpoint_type remote_endpoint(const implementation_type& impl,
00185       Error_Handler error_handler) const
00186   {
00187     logger_.log("Getting socket's remote endpoint");
00188     return service_impl_.remote_endpoint(impl, error_handler);
00189   }
00190 
00192   template <typename Error_Handler>
00193   void shutdown(implementation_type& impl,
00194       asio::socket_base::shutdown_type what, Error_Handler error_handler)
00195   {
00196     logger_.log("Shutting down socket");
00197     service_impl_.shutdown(impl, what, error_handler);
00198   }
00199 
00201   template <typename Const_Buffers, typename Error_Handler>
00202   std::size_t send(implementation_type& impl, const Const_Buffers& buffers,
00203       asio::socket_base::message_flags flags,
00204       Error_Handler error_handler)
00205   {
00206     logger_.log("Sending data on socket");
00207     return service_impl_.send(impl, buffers, flags, error_handler);
00208   }
00209 
00211   template <typename Handler>
00212   class send_handler
00213   {
00214   public:
00215     send_handler(Handler h, logger& l)
00216       : handler_(h),
00217         logger_(l)
00218     {
00219     }
00220 
00221     void operator()(const asio::error& e, std::size_t bytes_transferred)
00222     {
00223       if (e)
00224       {
00225         std::string msg = "Asynchronous send failed: ";
00226         msg += e.what();
00227         logger_.log(msg);
00228       }
00229       else
00230       {
00231         logger_.log("Asynchronous send succeeded");
00232       }
00233 
00234       handler_(e, bytes_transferred);
00235     }
00236 
00237   private:
00238     Handler handler_;
00239     logger& logger_;
00240   };
00241 
00243   template <typename Const_Buffers, typename Handler>
00244   void async_send(implementation_type& impl, const Const_Buffers& buffers,
00245       asio::socket_base::message_flags flags, Handler handler)
00246   {
00247     logger_.log("Starting asynchronous send");
00248     service_impl_.async_send(impl, buffers, flags,
00249         send_handler<Handler>(handler, logger_));
00250   }
00251 
00253   template <typename Mutable_Buffers, typename Error_Handler>
00254   std::size_t receive(implementation_type& impl, const Mutable_Buffers& buffers,
00255       asio::socket_base::message_flags flags,
00256       Error_Handler error_handler)
00257   {
00258     logger_.log("Receiving data on socket");
00259     return service_impl_.receive(impl, buffers, flags, error_handler);
00260   }
00261 
00263   template <typename Handler>
00264   class receive_handler
00265   {
00266   public:
00267     receive_handler(Handler h, logger& l)
00268       : handler_(h),
00269         logger_(l)
00270     {
00271     }
00272 
00273     void operator()(const asio::error& e, std::size_t bytes_transferred)
00274     {
00275       if (e)
00276       {
00277         std::string msg = "Asynchronous receive failed: ";
00278         msg += e.what();
00279         logger_.log(msg);
00280       }
00281       else
00282       {
00283         logger_.log("Asynchronous receive succeeded");
00284       }
00285 
00286       handler_(e, bytes_transferred);
00287     }
00288 
00289   private:
00290     Handler handler_;
00291     logger& logger_;
00292   };
00293 
00295   template <typename Mutable_Buffers, typename Handler>
00296   void async_receive(implementation_type& impl, const Mutable_Buffers& buffers,
00297       asio::socket_base::message_flags flags, Handler handler)
00298   {
00299     logger_.log("Starting asynchronous receive");
00300     service_impl_.async_receive(impl, buffers, flags,
00301         receive_handler<Handler>(handler, logger_));
00302   }
00303 
00304 private:
00306   service_impl_type& service_impl_;
00307 
00309   logger logger_;
00310 };
00311 
00312 } // namespace services
00313 
00314 #endif // SERVICES_STREAM_SOCKET_SERVICE_HPP
asio 0.3.7 Home | Reference | Tutorial | Examples | Design