pion-net
4.0.9
|
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