forb
socket.hpp
1 #ifndef LIBFORB_SOCKET_HPP
2 #define LIBFORB_SOCKET_HPP
3 
4 #include <string>
5 #include <unistd.h> // close
6 #include <cstring> // memset
7 #include <arpa/inet.h>
8 #include <sys/socket.h>
9 
10 #include <cassert>
11 #include <forb/stream/stream.hpp>
12 
13 namespace forb {
14  namespace streams {
15 
16  // Returns true if the machine is big endian
17  // (same byte order of network endianess).
18  inline bool is_big_endian() {
19  union {
20  uint32_t i;
21  char c[4];
22  } bint = {0x01020304};
23 
24  return bint.c[0] == 1;
25  }
26 
28  class socket : public virtual stream {
29  /* *********************************** ALIASES AND STATIC ATTRIBUTES ************************************ */
30  private:
31  using sockaddr_in_t = struct sockaddr_in;
32  using sockaddr_t = struct sockaddr;
33 
40  struct socket_create_t {
41  };
42 
43  // Constants used within the class
44  static constexpr int AF_TYPE = AF_INET;
45  static constexpr int PROTOCOL = SOCK_STREAM;
46  static constexpr socklen_t SOCKADDR_SIZE = sizeof(sockaddr_in_t);
47 
48  /* ********************************************* ATTRIBUTES ********************************************* */
49  private:
51  int _sock_fd = 0;
52 
54  std::string _local_address = "";
55 
57  int _local_port = 0;
58 
60  std::string _remote_address = "";
61 
63  int _remote_port = 0;
64 
66  bool _is_server = false;
67 
68  /* ******************************************** CONSTRUCTORS ******************************************** */
69  private:
77  socket(socket_create_t);
78 
81  socket(int sock_fd, const std::string &remote_address, int remote_port);
82 
85  socket(const std::string &remote_address, int remote_port);
86 
87  public:
89  socket() = default;
90 
91  /**********************************************************************************************************/
92 
94  ~socket() override {
95  close();
96  };
97 
99  socket(const socket &other) = delete;
100 
102  socket &operator=(const socket &other) = delete;
103 
106  socket(socket &&other) noexcept;
107 
110  socket &operator=(socket &&other) noexcept;
111 
112  /**********************************************************************************************************/
113 
114  // Following static methods are implicitly inline
115 
119  static socket make_server(int port, int listen_queue_size = 10) {
120  return make_server("", port, listen_queue_size);
121  }
122 
127  static socket make_server(const std::string &address, int port, int listen_queue_size = 10) {
128  socket new_socket = socket_create_t();
129  new_socket.bind(address, port);
130  new_socket.listen(listen_queue_size);
131  return new_socket;
132  }
133 
135  static socket make_client(const std::string &address, int port) {
136  socket new_socket = socket_create_t();
137  new_socket.connect(address, port);
138  return new_socket;
139  }
140 
141  /**********************************************************************************************************/
142  private:
145  static inline sockaddr_in_t build_sockaddr(const std::string &address, int port);
146 
148  void _move_attributes(socket &other) noexcept;
149 
150  /*
152  void bind(int port) {
153  return bind("", port);
154  };
155  */
156 
160  void bind(const std::string &address, int port);
161 
163  void listen(int listen_queue_size);
164 
166  void connect(const std::string &address, int port);
167 
168  public:
171  socket accept();
172 
175  void send(const void *buffer, std::size_t size) override;
176 
179  void recv(void *buffer, std::size_t size) override;
180 
182  void close() noexcept override;
183 
185  type get_type() const override {
186  return type::SOCKET;
187  };
188 
193  bool require_marshal() const override {
194  return !is_big_endian();
195  };
196  };
197 
198  } // namespace streams
199 
200 } // namespace forb
201 
202 #endif // #ifndef LIBFORB_SOCKET_HPP
static socket make_server(int port, int listen_queue_size=10)
Creates a new server socket.
Definition: socket.hpp:119
C++ wrapper of the Socket POSIX API, which uses IPv4 and blocking communication.
Definition: socket.hpp:28
type get_type() const override
Returns the type of the stream.
Definition: socket.hpp:185
bool require_marshal() const override
Returns true if the execution platform requires marshalling before sending data on the socket...
Definition: socket.hpp:193
Virtual class that represents a stream.
Definition: stream.hpp:69
~socket() override
Virtual destructor that closes the socket (if open).
Definition: socket.hpp:94
void close() noexcept override
Closes the socket, called by the virtual destructor.
Definition: socket.cpp:37
This function implements a memcpy abstract that is valid also for volatile data.
Definition: base_skeleton.hpp:15
void recv(void *buffer, std::size_t size) override
Blocking wrapper of the POSIX recv function.
Definition: socket.cpp:264
static socket make_client(const std::string &address, int port)
Creates a new client socket, connected to the specified remote host.
Definition: socket.hpp:135
void send(const void *buffer, std::size_t size) override
Blocking wrapper of the POSIX send function.
Definition: socket.cpp:228
type
The type of the stream.
Definition: stream.hpp:78
static socket make_server(const std::string &address, int port, int listen_queue_size=10)
Creates a new server socket.
Definition: socket.hpp:127
socket & operator=(const socket &other)=delete
This class does not support copy assignment.
socket accept()
Performs the accept operation on the given server socket.
Definition: socket.cpp:181
socket()=default
Default constructor, creates an empty socket, which cannot be used to exchange data.