tcp_socket.hpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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 <cstdint>
  24. #include <string>
  25. #include <vector>
  26. #include <tacopie/utils/typedefs.hpp>
  27. namespace tacopie {
  28. //!
  29. //! tacopie::tcp_socket is the class providing low-level TCP socket features.
  30. //! The tcp_socket provides a simple but convenient abstraction to unix and windows sockets.
  31. //! It also provides a socket type checker to ensure that server-only operations are only processable on server sockets, and client-only operations are only processable on client sockets.
  32. //!
  33. class tcp_socket {
  34. public:
  35. //!
  36. //! possible types of a TCP socket, either a client or a server
  37. //! type is used to prevent the used of client specific operations on a server socket (and vice-versa)
  38. //!
  39. //! UNKNOWN is used when socket type could not be determined for now
  40. //!
  41. enum class type {
  42. CLIENT,
  43. SERVER,
  44. UNKNOWN
  45. };
  46. public:
  47. //! ctor
  48. tcp_socket(void);
  49. //! dtor
  50. ~tcp_socket(void) = default;
  51. //!
  52. //! custom ctor
  53. //! build socket from existing file descriptor
  54. //!
  55. //! \param fd fd of the raw socket that will be used to init the tcp_socket object
  56. //! \param host host associated to the socket
  57. //! \param port port associated to the socket
  58. //! \param t type of the socket (client or server)
  59. tcp_socket(fd_t fd, const std::string& host, std::uint32_t port, type t);
  60. //! move ctor
  61. tcp_socket(tcp_socket&&);
  62. //! copy ctor
  63. tcp_socket(const tcp_socket&) = delete;
  64. //! assignment operator
  65. tcp_socket& operator=(const tcp_socket&) = delete;
  66. public:
  67. //!
  68. //! comparison operator
  69. //!
  70. //! \return true when the underlying sockets are the same (same file descriptor and socket type).
  71. //!
  72. bool operator==(const tcp_socket& rhs) const;
  73. //!
  74. //! comparison operator
  75. //!
  76. //! \return true when the underlying sockets are different (different file descriptor or socket type).
  77. //!
  78. bool operator!=(const tcp_socket& rhs) const;
  79. public:
  80. //!
  81. //! Read data synchronously from the underlying socket.
  82. //! The socket must be of type client to process this operation. If the type of the socket is unknown, the socket type will be set to client.
  83. //!
  84. //! \param size_to_read Number of bytes to read (might read less than requested)
  85. //! \return Returns the read bytes
  86. //!
  87. std::vector<char> recv(std::size_t size_to_read);
  88. //!
  89. //! Send data synchronously to the underlying socket.
  90. //! The socket must be of type client to process this operation. If the type of the socket is unknown, the socket type will be set to client.
  91. //!
  92. //! \param data Buffer containing bytes to be written
  93. //! \param size_to_write Number of bytes to send
  94. //! \return Returns the number of bytes that were effectively sent.
  95. //!
  96. std::size_t send(const std::vector<char>& data, std::size_t size_to_write);
  97. //!
  98. //! Connect the socket to the remote server.
  99. //! The socket must be of type client to process this operation. If the type of the socket is unknown, the socket type will be set to client.
  100. //!
  101. //! \param host Hostname of the target server
  102. //! \param port Port of the target server
  103. //! \param timeout_msecs maximum time to connect (will block until connect succeed or timeout expire). 0 will block undefinitely. If timeout expires, connection fails
  104. //!
  105. void connect(const std::string& host, std::uint32_t port, std::uint32_t timeout_msecs = 0);
  106. //!
  107. //! Binds the socket to the given host and port.
  108. //! The socket must be of type server to process this operation. If the type of the socket is unknown, the socket type will be set to server.
  109. //!
  110. //! \param host Hostname to be bind to
  111. //! \param port Port to be bind to
  112. //!
  113. void bind(const std::string& host, std::uint32_t port);
  114. //!
  115. //! Make the socket listen for incoming connections.
  116. //! Socket must be of type server to process this operation. If the type of the socket is unknown, the socket type will be set to server.
  117. //!
  118. //! \param max_connection_queue Size of the queue for incoming connections to be processed by the server
  119. //!
  120. void listen(std::size_t max_connection_queue);
  121. //!
  122. //! Accept a new incoming connection.
  123. //! The socket must be of type server to process this operation. If the type of the socket is unknown, the socket type will be set to server.
  124. //!
  125. //! \return Return the tcp_socket associated to the newly accepted connection.
  126. //!
  127. tcp_socket accept(void);
  128. //!
  129. //! Close the underlying socket.
  130. //!
  131. void close(void);
  132. public:
  133. //!
  134. //! \return the hostname associated with the underlying socket.
  135. //!
  136. const std::string& get_host(void) const;
  137. //!
  138. //! \return the port associated with the underlying socket.
  139. //!
  140. std::uint32_t get_port(void) const;
  141. //!
  142. //! \return the type associated with the underlying socket.
  143. //!
  144. type get_type(void) const;
  145. //!
  146. //! set type, should be used if some operations determining socket type
  147. //! have been done on the behalf of the tcp_socket instance
  148. //!
  149. //! \param t type of the socket
  150. //!
  151. void set_type(type t);
  152. //!
  153. //! direct access to the underlying fd
  154. //!
  155. //! \return underlying socket fd
  156. //!
  157. fd_t get_fd(void) const;
  158. public:
  159. //!
  160. //! \return whether the host is IPV6
  161. //!
  162. bool is_ipv6(void) const;
  163. private:
  164. //!
  165. //! create a new socket if no socket has been initialized yet
  166. //!
  167. void create_socket_if_necessary(void);
  168. //!
  169. //! check whether the current socket has an approriate type for that kind of operation
  170. //! if current type is UNKNOWN, update internal type with given type
  171. //!
  172. //! \param t expected type of our socket to process the operation
  173. //!
  174. void check_or_set_type(type t);
  175. private:
  176. //!
  177. //! fd associated to the socket
  178. //!
  179. fd_t m_fd;
  180. //!
  181. //! socket hostname information
  182. //!
  183. std::string m_host;
  184. //!
  185. //! socket port information
  186. //!
  187. std::uint32_t m_port;
  188. //!
  189. //! type of the socket
  190. //!
  191. type m_type;
  192. };
  193. } // namespace tacopie