TCPServer.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. //
  2. // TCPServer.h
  3. //
  4. // Library: Net
  5. // Package: TCPServer
  6. // Module: TCPServer
  7. //
  8. // Definition of the TCPServer class.
  9. //
  10. // Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
  11. // and Contributors.
  12. //
  13. // SPDX-License-Identifier: BSL-1.0
  14. //
  15. #ifndef Net_TCPServer_INCLUDED
  16. #define Net_TCPServer_INCLUDED
  17. #include "Poco/Net/Net.h"
  18. #include "Poco/Net/ServerSocket.h"
  19. #include "Poco/Net/TCPServerConnectionFactory.h"
  20. #include "Poco/Net/TCPServerParams.h"
  21. #include "Poco/RefCountedObject.h"
  22. #include "Poco/AutoPtr.h"
  23. #include "Poco/Runnable.h"
  24. #include "Poco/Thread.h"
  25. #include "Poco/ThreadPool.h"
  26. #include <atomic>
  27. namespace Poco {
  28. namespace Net {
  29. class TCPServerDispatcher;
  30. class StreamSocket;
  31. class Net_API TCPServerConnectionFilter: public Poco::RefCountedObject
  32. /// A TCPServerConnectionFilter can be used to reject incoming connections
  33. /// before passing them on to the TCPServerDispatcher and
  34. /// starting a thread to handle them.
  35. ///
  36. /// An example use case is white-list or black-list IP address filtering.
  37. ///
  38. /// Subclasses must override the accept() method.
  39. {
  40. public:
  41. typedef Poco::AutoPtr<TCPServerConnectionFilter> Ptr;
  42. virtual bool accept(const StreamSocket& socket) = 0;
  43. /// Returns true if the given StreamSocket connection should
  44. /// be handled, and passed on to the TCPServerDispatcher.
  45. ///
  46. /// Returns false if the socket should be closed immediately.
  47. ///
  48. /// The socket can be prevented from being closed immediately
  49. /// if false is returned by creating a copy of the socket.
  50. /// This can be used to handle certain socket connections in
  51. /// a special way, outside the TCPServer framework.
  52. protected:
  53. virtual ~TCPServerConnectionFilter();
  54. };
  55. class Net_API TCPServer: public Poco::Runnable
  56. /// This class implements a multithreaded TCP server.
  57. ///
  58. /// The server uses a ServerSocket to listen for incoming
  59. /// connections. The ServerSocket must have been bound to
  60. /// an address before it is passed to the TCPServer constructor.
  61. /// Additionally, the ServerSocket must be put into listening
  62. /// state before the TCPServer is started by calling the start()
  63. /// method.
  64. ///
  65. /// The server uses a thread pool to assign threads to incoming
  66. /// connections. Before incoming connections are assigned to
  67. /// a connection thread, they are put into a queue.
  68. /// Connection threads fetch new connections from the queue as soon
  69. /// as they become free. Thus, a connection thread may serve more
  70. /// than one connection.
  71. ///
  72. /// As soon as a connection thread fetches the next connection from
  73. /// the queue, it creates a TCPServerConnection object for it
  74. /// (using the TCPServerConnectionFactory passed to the constructor)
  75. /// and calls the TCPServerConnection's start() method. When the
  76. /// start() method returns, the connection object is deleted.
  77. ///
  78. /// The number of connection threads is adjusted dynamically, depending
  79. /// on the number of connections waiting to be served.
  80. ///
  81. /// It is possible to specify a maximum number of queued connections.
  82. /// This prevents the connection queue from overflowing in the
  83. /// case of an extreme server load. In such a case, connections that
  84. /// cannot be queued are silently and immediately closed.
  85. ///
  86. /// TCPServer uses a separate thread to accept incoming connections.
  87. /// Thus, the call to start() returns immediately, and the server
  88. /// continues to run in the background.
  89. ///
  90. /// To stop the server from accepting new connections, call stop().
  91. ///
  92. /// After calling stop(), no new connections will be accepted and
  93. /// all queued connections will be discarded.
  94. /// Already served connections, however, will continue being served.
  95. {
  96. public:
  97. TCPServer(TCPServerConnectionFactory::Ptr pFactory, Poco::UInt16 portNumber = 0, TCPServerParams::Ptr pParams = 0);
  98. /// Creates the TCPServer, with ServerSocket listening on the given port.
  99. /// Default port is zero, allowing any available port. The port number
  100. /// can be queried through TCPServer::port() member.
  101. ///
  102. /// The server takes ownership of the TCPServerConnectionFactory
  103. /// and deletes it when it's no longer needed.
  104. ///
  105. /// The server also takes ownership of the TCPServerParams object.
  106. /// If no TCPServerParams object is given, the server's TCPServerDispatcher
  107. /// creates its own one.
  108. ///
  109. /// New threads are taken from the default thread pool.
  110. TCPServer(TCPServerConnectionFactory::Ptr pFactory, const ServerSocket& socket, TCPServerParams::Ptr pParams = 0);
  111. /// Creates the TCPServer, using the given ServerSocket.
  112. ///
  113. /// The server takes ownership of the TCPServerConnectionFactory
  114. /// and deletes it when it's no longer needed.
  115. ///
  116. /// The server also takes ownership of the TCPServerParams object.
  117. /// If no TCPServerParams object is given, the server's TCPServerDispatcher
  118. /// creates its own one.
  119. ///
  120. /// New threads are taken from the default thread pool.
  121. TCPServer(TCPServerConnectionFactory::Ptr pFactory, Poco::ThreadPool& threadPool, const ServerSocket& socket, TCPServerParams::Ptr pParams = 0);
  122. /// Creates the TCPServer, using the given ServerSocket.
  123. ///
  124. /// The server takes ownership of the TCPServerConnectionFactory
  125. /// and deletes it when it's no longer needed.
  126. ///
  127. /// The server also takes ownership of the TCPServerParams object.
  128. /// If no TCPServerParams object is given, the server's TCPServerDispatcher
  129. /// creates its own one.
  130. ///
  131. /// New threads are taken from the given thread pool.
  132. virtual ~TCPServer();
  133. /// Destroys the TCPServer and its TCPServerConnectionFactory.
  134. const TCPServerParams& params() const;
  135. /// Returns a const reference to the TCPServerParam object
  136. /// used by the server's TCPServerDispatcher.
  137. void start();
  138. /// Starts the server. A new thread will be
  139. /// created that waits for and accepts incoming
  140. /// connections.
  141. ///
  142. /// Before start() is called, the ServerSocket passed to
  143. /// TCPServer must have been bound and put into listening state.
  144. void stop();
  145. /// Stops the server.
  146. ///
  147. /// No new connections will be accepted.
  148. /// Already handled connections will continue to be served.
  149. ///
  150. /// Once the server has been stopped, it cannot be restarted.
  151. int currentThreads() const;
  152. /// Returns the number of currently used connection threads.
  153. int maxThreads() const;
  154. /// Returns the maximum number of threads available.
  155. int totalConnections() const;
  156. /// Returns the total number of handled connections.
  157. int currentConnections() const;
  158. /// Returns the number of currently handled connections.
  159. int maxConcurrentConnections() const;
  160. /// Returns the maximum number of concurrently handled connections.
  161. int queuedConnections() const;
  162. /// Returns the number of queued connections.
  163. int refusedConnections() const;
  164. /// Returns the number of refused connections.
  165. const ServerSocket& socket() const;
  166. /// Returns the underlying server socket.
  167. Poco::UInt16 port() const;
  168. /// Returns the port the server socket listens on.
  169. void setConnectionFilter(const TCPServerConnectionFilter::Ptr& pFilter);
  170. /// Sets a TCPServerConnectionFilter. Can also be used to remove
  171. /// a filter by passing a null pointer.
  172. ///
  173. /// To avoid a potential race condition, the filter must
  174. /// be set before the TCPServer is started. Trying to set
  175. /// the filter after start() has been called will trigger
  176. /// an assertion.
  177. TCPServerConnectionFilter::Ptr getConnectionFilter() const;
  178. /// Returns the TCPServerConnectionFilter set with setConnectionFilter(),
  179. /// or null pointer if no filter has been set.
  180. protected:
  181. void run();
  182. /// Runs the server. The server will run until
  183. /// the stop() method is called, or the server
  184. /// object is destroyed, which implicitly calls
  185. /// the stop() method.
  186. static std::string threadName(const ServerSocket& socket);
  187. /// Returns a thread name for the server thread.
  188. private:
  189. TCPServer();
  190. TCPServer(const TCPServer&);
  191. TCPServer& operator = (const TCPServer&);
  192. ServerSocket _socket;
  193. TCPServerDispatcher* _pDispatcher;
  194. TCPServerConnectionFilter::Ptr _pConnectionFilter;
  195. Poco::Thread _thread;
  196. std::atomic<bool> _stopped;
  197. };
  198. //
  199. // inlines
  200. //
  201. inline const ServerSocket& TCPServer::socket() const
  202. {
  203. return _socket;
  204. }
  205. inline Poco::UInt16 TCPServer::port() const
  206. {
  207. return _socket.address().port();
  208. }
  209. inline TCPServerConnectionFilter::Ptr TCPServer::getConnectionFilter() const
  210. {
  211. return _pConnectionFilter;
  212. }
  213. } } // namespace Poco::Net
  214. #endif // Net_TCPServer_INCLUDED