| Home | Libraries | People | FAQ | More

# 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 <boost/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 boost::asio::io_service::service
    00015 {
    00016 private:
    00018   typedef boost::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(boost::asio::io_service& io_service)
    00035     : boost::asio::io_service::service(io_service),
    00036       service_impl_(boost::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 boost::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       boost::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       boost::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 boost::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       boost::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       boost::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 boost::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       boost::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

| Copyright © 2003 - 2006 Christopher M. Kohlhoff