tcp_server.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // MIT License
  2. //
  3. // Copyright (c) 2016-2017 Simon Ninon <simon.ninon@gmail.com>
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in all
  13. // copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21. // SOFTWARE.
  22. #pragma once
  23. #include <atomic>
  24. #include <cstdint>
  25. #include <list>
  26. #include <memory>
  27. #include <mutex>
  28. #include <string>
  29. #include <tacopie/network/io_service.hpp>
  30. #include <tacopie/network/tcp_client.hpp>
  31. #include <tacopie/network/tcp_socket.hpp>
  32. #include <tacopie/utils/typedefs.hpp>
  33. #define __TACOPIE_CONNECTION_QUEUE_SIZE 1024
  34. namespace tacopie {
  35. //!
  36. //! tacopie::tcp_server is the class providing TCP Server features.
  37. //! The tcp_server works entirely asynchronously, waiting for the io_service to notify whenever a new client wished to connect.
  38. //!
  39. class tcp_server {
  40. public:
  41. //! ctor
  42. tcp_server(void);
  43. //! dtor
  44. ~tcp_server(void);
  45. //! copy ctor
  46. tcp_server(const tcp_server&) = delete;
  47. //! assignment operator
  48. tcp_server& operator=(const tcp_server&) = delete;
  49. public:
  50. //!
  51. //! comparison operator
  52. //!
  53. //! \return true when the underlying sockets are the same (same file descriptor and socket type).
  54. //!
  55. bool operator==(const tcp_server& rhs) const;
  56. //!
  57. //! comparison operator
  58. //!
  59. //! \return true when the underlying sockets are different (different file descriptor or socket type).
  60. //!
  61. bool operator!=(const tcp_server& rhs) const;
  62. public:
  63. //!
  64. //! callback called whenever a new client is connecting to the server
  65. //!
  66. //! Takes as parameter a shared pointer to the tcp_client that wishes to connect
  67. //! Returning true means connection is handled by tcp_client wrapper and nothing will be done by tcp_server. Returning false means connection is handled by tcp_server, will be stored in an internal list and tcp_client disconection_handler overriden.
  68. //!
  69. typedef std::function<bool(const std::shared_ptr<tcp_client>&)> on_new_connection_callback_t;
  70. //!
  71. //! Start the tcp_server at the given host and port.
  72. //!
  73. //! \param host hostname to be connected to
  74. //! \param port port to be connected to
  75. //! \param callback callback to be called on new connections (may be null, connections are then handled automatically by the tcp_server object)
  76. //!
  77. void start(const std::string& host, std::uint32_t port, const on_new_connection_callback_t& callback = nullptr);
  78. //!
  79. //! Disconnect the tcp_server if it was currently running.
  80. //!
  81. //! \param wait_for_removal When sets to true, disconnect blocks until the underlying TCP server has been effectively removed from the io_service and that all the underlying callbacks have completed.
  82. //! \param recursive_wait_for_removal When sets to true and wait_for_removal is also set to true, blocks until all the underlying TCP client connected to the TCP server have been effectively removed from the io_service and that all the underlying callbacks have completed.
  83. //!
  84. void stop(bool wait_for_removal = false, bool recursive_wait_for_removal = true);
  85. //!
  86. //! \return whether the server is currently running or not
  87. ///!
  88. bool is_running(void) const;
  89. public:
  90. //!
  91. //! \return the tacopie::tcp_socket associated to the server. (non-const version)
  92. //!
  93. tcp_socket& get_socket(void);
  94. //!
  95. //! \return the tacopie::tcp_socket associated to the server. (const version)
  96. //!
  97. const tcp_socket& get_socket(void) const;
  98. public:
  99. //!
  100. //! \return io service monitoring this tcp connection
  101. //!
  102. const std::shared_ptr<tacopie::io_service>& get_io_service(void) const;
  103. public:
  104. //!
  105. //! \return the list of tacopie::tcp_client connected to the server.
  106. //!
  107. const std::list<std::shared_ptr<tacopie::tcp_client>>& get_clients(void) const;
  108. private:
  109. //!
  110. //! io service read callback
  111. //!
  112. //! \param fd socket that triggered the read callback
  113. //!
  114. void on_read_available(fd_t fd);
  115. //!
  116. //! client disconnected
  117. //! called whenever a client disconnected from the tcp_server
  118. //!
  119. //! \param client disconnected client
  120. //!
  121. void on_client_disconnected(const std::shared_ptr<tcp_client>& client);
  122. private:
  123. //!
  124. //! store io_service
  125. //! prevent deletion of io_service before the tcp_server itself
  126. //!
  127. std::shared_ptr<io_service> m_io_service;
  128. //1
  129. //! server socket
  130. //!
  131. tacopie::tcp_socket m_socket;
  132. //!
  133. //! whether the server is currently running or not
  134. //!
  135. std::atomic<bool> m_is_running = ATOMIC_VAR_INIT(false);
  136. //!
  137. //! clients
  138. //!
  139. std::list<std::shared_ptr<tacopie::tcp_client>> m_clients;
  140. //!
  141. //! clients thread safety
  142. //!
  143. std::mutex m_clients_mtx;
  144. //!
  145. //! on new connection callback
  146. //!
  147. on_new_connection_callback_t m_on_new_connection_callback;
  148. };
  149. } // namespace tacopie