libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
socket_wrapper_asio.hpp
Go to the documentation of this file.
1 #ifndef LIBJMMCG_CORE_SOCKET_WRAPPER_ASIO_HPP
2 #define LIBJMMCG_CORE_SOCKET_WRAPPER_ASIO_HPP
3 
4 /******************************************************************************
5 ** Copyright © 2015 by J.M.McGuiness, coder@hussar.me.uk
6 **
7 ** This library is free software; you can redistribute it and/or
8 ** modify it under the terms of the GNU Lesser General Public
9 ** License as published by the Free Software Foundation; either
10 ** version 2.1 of the License, or (at your option) any later version.
11 **
12 ** This library is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ** Lesser General Public License for more details.
16 **
17 ** You should have received a copy of the GNU Lesser General Public
18 ** License along with this library; if not, write to the Free Software
19 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 
22 #include "socket_wrapper.hpp"
23 
24 #include <boost/asio.hpp>
25 
26 #include <iostream>
27 
28 namespace jmmcg { namespace LIBJMMCG_VER_NAMESPACE { namespace socket { namespace asio {
29 
30 /// A simple TCP/IP socket wrapper using boost::asio.
31 /**
32  Developed from:
33  <a href="https://www.boost.org/doc/libs/1_71_0/doc/html/boost_asio/example/cpp11/echo/blocking_tcp_echo_client.cpp"/>
34 */
35 template<class LkT>
37 public:
38  using socket_t=boost::asio::ip::tcp::socket;
39  using socket_priority=socket::socket_priority;
40  /// The lock-type to use to ensure that the underlying ::write()s occur atomically.
41  /**
42  The calls to the underlying socket ::write() may occur multiple times when under extreme load. This lock is used to ensure that the calls to write() occur atomically with respect to multiple threads.
43 
44  \see ::write()
45  */
46  using write_lock_t=LkT;
47  using atomic_t=typename write_lock_t::atomic_t;
48 
49  /// Wrap a TCP socket using the TCP/IP protocol.
50  /**
51  \param io_context The I/O context that underlies the socket.
52  */
53  explicit socket_wrapper(boost::asio::io_context &io_context);
54  /// Wrap a TCP socket using the TCP/IP protocol.
55  /**
56  \param socket The socket to be taken control of.
57  */
58  explicit socket_wrapper(socket_t &&socket);
59 
60  void connect(boost::asio::ip::tcp::endpoint const &endpoint);
61 
62  /// Write the whole message to the socket in one go.
63  /**
64  \param message The message to write, that must be as-if a POD.
65  */
66  template<
67  class MsgT ///< The type of the message to write.
68  >
69  void write(MsgT const &message) noexcept(false);
70 
71  /// Write the whole message to the socket in one go.
72  /**
73  \param message The message to write, that must be as-if a POD.
74  */
75  template<class V, std::size_t N>
76  void write(std::array<V, N> const &message) noexcept(false);
77 
78  /// Read the whole message from the socket in one go.
79  /**
80  \param dest The message will be placed into this buffer, which may be grown to accommodate the message.
81  */
82  template<
83  class MsgT ///< The type of the message to read, that must be as-if a POD.
84  >
85  void read(MsgT &dest) noexcept(false);
86  /// Read the whole message from the socket in one go.
87  /**
88  \param dest The message will be placed into this stack-based buffer, which must be sufficiently large to accommodate the message read, otherwise UB will result.
89  */
90  template<class V, std::size_t SrcSz> void
91  read(V (& dest)[SrcSz]) noexcept(false);
92 
93  template<class MsgDetails, class V, std::size_t N> bool
94  read(std::array<V, N> &buff) noexcept(false);
95 
96  bool is_open() const;
97 
98  void close();
99 
100  void set_options(std::size_t, std::size_t max_message_size, unsigned short timeout, socket_priority priority, std::size_t incoming_cpu);
101 
102  std::string to_string() const noexcept(false);
103 
104 protected:
105  mutable atomic_t mutex_;
106 
107 private:
108  socket_t socket_;
109 };
110 
111 template<class LkT>
112 inline std::ostream &
113 operator<<(std::ostream &os, socket_wrapper<LkT> const &ec) noexcept(false);
114 
115 } } } }
116 
118 
119 #endif