net/include/pion/net/TCPServer.hpp

00001 // ------------------------------------------------------------------
00002 // pion-net: a C++ framework for building lightweight HTTP interfaces
00003 // ------------------------------------------------------------------
00004 // Copyright (C) 2007-2008 Atomic Labs, Inc.  (http://www.atomiclabs.com)
00005 //
00006 // Distributed under the Boost Software License, Version 1.0.
00007 // See http://www.boost.org/LICENSE_1_0.txt
00008 //
00009 
00010 #ifndef __PION_TCPSERVER_HEADER__
00011 #define __PION_TCPSERVER_HEADER__
00012 
00013 #include <set>
00014 #include <boost/asio.hpp>
00015 #include <boost/noncopyable.hpp>
00016 #include <boost/shared_ptr.hpp>
00017 #include <boost/thread/mutex.hpp>
00018 #include <boost/thread/condition.hpp>
00019 #include <pion/PionConfig.hpp>
00020 #include <pion/PionLogger.hpp>
00021 #include <pion/PionScheduler.hpp>
00022 #include <pion/net/TCPConnection.hpp>
00023 
00024 
00025 namespace pion {    // begin namespace pion
00026 namespace net {     // begin namespace net (Pion Network Library)
00027 
00031 class PION_NET_API TCPServer :
00032     private boost::noncopyable
00033 {
00034 public:
00035 
00037     virtual ~TCPServer() { if (m_is_listening) stop(false); }
00038     
00040     void start(void);
00041 
00047     void stop(bool wait_until_finished = false);
00048     
00050     void join(void);
00051     
00057     void setSSLKeyFile(const std::string& pem_key_file);
00058 
00060     std::size_t getConnections(void) const;
00061 
00063     inline unsigned int getPort(void) const { return m_endpoint.port(); }
00064     
00066     inline void setPort(unsigned int p) { m_endpoint.port(p); }
00067     
00069     inline boost::asio::ip::address getAddress(void) const { return m_endpoint.address(); }
00070     
00072     inline void setAddress(const boost::asio::ip::address& addr) { m_endpoint.address(addr); }
00073     
00075     inline const boost::asio::ip::tcp::endpoint& getEndpoint(void) const { return m_endpoint; }
00076     
00078     inline void setEndpoint(const boost::asio::ip::tcp::endpoint& ep) { m_endpoint = ep; }
00079 
00081     inline bool getSSLFlag(void) const { return m_ssl_flag; }
00082     
00084     inline void setSSLFlag(bool b = true) { m_ssl_flag = b; }
00085     
00087     inline TCPConnection::SSLContext& getSSLContext(void) { return m_ssl_context; }
00088     
00090     inline bool isListening(void) const { return m_is_listening; }
00091     
00093     inline void setLogger(PionLogger log_ptr) { m_logger = log_ptr; }
00094     
00096     inline PionLogger getLogger(void) { return m_logger; }
00097     
00098 
00099 protected:
00100         
00106     explicit TCPServer(const unsigned int tcp_port);
00107     
00113     explicit TCPServer(const boost::asio::ip::tcp::endpoint& endpoint);
00114 
00121     explicit TCPServer(PionScheduler& scheduler, const unsigned int tcp_port = 0);
00122     
00129     TCPServer(PionScheduler& scheduler, const boost::asio::ip::tcp::endpoint& endpoint);
00130     
00137     virtual void handleConnection(TCPConnectionPtr& tcp_conn) {
00138         tcp_conn->setLifecycle(TCPConnection::LIFECYCLE_CLOSE); // make sure it will get closed
00139         tcp_conn->finish();
00140     }
00141     
00143     virtual void beforeStarting(void) {}
00144 
00146     virtual void afterStopping(void) {}
00147     
00149     inline boost::asio::io_service& getIOService(void) { return m_active_scheduler.getIOService(); }
00150     
00151     
00153     PionLogger                  m_logger;
00154     
00155     
00156 private:
00157         
00159     void handleStopRequest(void);
00160     
00162     void listen(void);
00163 
00170     void handleAccept(TCPConnectionPtr& tcp_conn,
00171                       const boost::system::error_code& accept_error);
00172 
00179     void handleSSLHandshake(TCPConnectionPtr& tcp_conn,
00180                             const boost::system::error_code& handshake_error);
00181     
00186     void finishConnection(TCPConnectionPtr& tcp_conn);
00187     
00190     std::size_t pruneConnections(void);
00191     
00193     typedef std::set<TCPConnectionPtr>      ConnectionPool;
00194     
00195     
00197     PionSingleServiceScheduler              m_default_scheduler;
00198 
00200     PionScheduler &                         m_active_scheduler;
00201     
00203     boost::asio::ip::tcp::acceptor          m_tcp_acceptor;
00204 
00206     TCPConnection::SSLContext               m_ssl_context;
00207         
00209     boost::condition                        m_server_has_stopped;
00210 
00212     boost::condition                        m_no_more_connections;
00213 
00215     ConnectionPool                          m_conn_pool;
00216 
00218     boost::asio::ip::tcp::endpoint          m_endpoint;
00219 
00221     bool                                    m_ssl_flag;
00222 
00224     bool                                    m_is_listening;
00225 
00227     mutable boost::mutex                    m_mutex;
00228 };
00229 
00230 
00232 typedef boost::shared_ptr<TCPServer>    TCPServerPtr;
00233 
00234 
00235 }   // end namespace net
00236 }   // end namespace pion
00237 
00238 #endif

Generated on Fri Apr 30 14:48:53 2010 for pion-net by  doxygen 1.4.7