sockpp
Modern C++ socket library wrapper
socket.h
Go to the documentation of this file.
1 
13 // --------------------------------------------------------------------------
14 // This file is part of the "sockpp" C++ socket library.
15 //
16 // Copyright (c) 2014-2019 Frank Pagliughi
17 // All rights reserved.
18 //
19 // Redistribution and use in source and binary forms, with or without
20 // modification, are permitted provided that the following conditions are
21 // met:
22 //
23 // 1. Redistributions of source code must retain the above copyright notice,
24 // this list of conditions and the following disclaimer.
25 //
26 // 2. Redistributions in binary form must reproduce the above copyright
27 // notice, this list of conditions and the following disclaimer in the
28 // documentation and/or other materials provided with the distribution.
29 //
30 // 3. Neither the name of the copyright holder nor the names of its
31 // contributors may be used to endorse or promote products derived from this
32 // software without specific prior written permission.
33 //
34 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
35 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
36 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
37 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
38 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
39 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
40 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
41 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
42 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
43 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45 // --------------------------------------------------------------------------
46 
47 #ifndef __sockpp_socket_h
48 #define __sockpp_socket_h
49 
50 #include "sockpp/sock_address.h"
51 #include <chrono>
52 #include <string>
53 #include <tuple>
54 
55 namespace sockpp {
56 
58 
59 #if !defined(SOCKPP_SOCKET_T_DEFINED)
60  typedef int socket_t;
61  const socket_t INVALID_SOCKET = -1;
62  #define SOCKPP_SOCKET_T_DEFINED
63 #endif
64 
65 
66 timeval to_timeval(const std::chrono::microseconds& dur);
67 
68 template<class Rep, class Period>
69 timeval to_timeval(const std::chrono::duration<Rep,Period>& dur) {
70  return to_timeval(std::chrono::duration_cast<std::chrono::microseconds>(dur));
71 }
72 
74 
84 class socket
85 {
87  socket_t handle_;
89  mutable int lastErr_;
95  bool close(socket_t h);
96 
97  // Non-copyable.
98  socket(const socket&) =delete;
99  socket& operator=(const socket&) =delete;
100 
101 protected:
111  bool close_on_err() {
112  close(release());
113  return false;
114  }
121  static int get_last_error();
127  void set_last_error() {
128  lastErr_ = get_last_error();
129  }
136  template <typename T>
137  T check_ret(T ret) const{
138  lastErr_ = (ret < 0) ? get_last_error() : 0;
139  return ret;
140  }
148  template <typename T>
149  bool check_ret_bool(T ret) const{
150  lastErr_ = (ret < 0) ? get_last_error() : 0;
151  return ret >= 0;
152  }
161  socket_t check_socket(socket_t ret) const {
162  lastErr_ = (ret == INVALID_SOCKET) ? get_last_error() : 0;
163  return ret;
164  }
174  bool check_socket_bool(socket_t ret) const{
175  lastErr_ = (ret == INVALID_SOCKET) ? get_last_error() : 0;
176  return ret != INVALID_SOCKET;
177  }
178 
179 public:
183  socket() : handle_(INVALID_SOCKET), lastErr_(0) {}
190  explicit socket(socket_t h) : handle_(h), lastErr_(0) {}
196  socket(socket&& sock) noexcept
197  : handle_(sock.handle_), lastErr_(sock.lastErr_) {
198  sock.handle_ = INVALID_SOCKET;
199  }
203  virtual ~socket() { close(); }
209  static void initialize();
215  static void destroy();
233  static socket create(int domain, int type, int protocol=0);
238  bool is_open() const { return handle_ != INVALID_SOCKET; }
244  bool operator!() const {
245  return handle_ == INVALID_SOCKET || lastErr_ != 0;
246  }
252  explicit operator bool() const {
253  return handle_ != INVALID_SOCKET && lastErr_ == 0;
254  }
259  socket_t handle() const { return handle_; }
266  virtual sa_family_t family() const {
267  return address().family();
268  }
280  socket clone() const;
301  static std::tuple<socket, socket> pair(int domain, int type, int protocol=0);
306  void clear(int val=0) { lastErr_ = val; }
311  socket_t release() {
312  socket_t h = handle_;
313  handle_ = INVALID_SOCKET;
314  return h;
315  }
320  void reset(socket_t h=INVALID_SOCKET);
327  socket& operator=(socket&& sock) noexcept {
328  // Give our handle to the other to close.
329  std::swap(handle_, sock.handle_);
330  lastErr_ = sock.lastErr_;
331  return *this;
332  }
338  bool bind(const sock_address& addr);
343  sock_address_any address() const;
364  bool get_option(int level, int optname, void* optval, socklen_t* optlen) const;
375  template <typename T>
376  bool get_option(int level, int optname, T* val) const {
377  socklen_t len = sizeof(T);
378  return get_option(level, optname, (void*) val, &len);
379  }
394  bool set_option(int level, int optname, const void* optval, socklen_t optlen);
406  template <typename T>
407  bool set_option(int level, int optname, const T& val) {
408  return set_option(level, optname, (void*) &val, sizeof(T));
409  }
418  bool set_non_blocking(bool on=true);
425  static std::string error_str(int errNum);
431  int last_error() const { return lastErr_; }
437  std::string last_error_str() const {
438  return error_str(lastErr_);
439  }
448  bool shutdown(int how=SHUT_RDWR);
455  bool close();
456 };
457 
459 
471 {
472 public:
475 };
476 
478 // end namespace sockpp
479 }
480 
481 #endif // __sockpp_socket_h
482 
Generic socket address.
Definition: sock_address.h:64
static std::tuple< socket, socket > pair(int domain, int type, int protocol=0)
Creates a pair of connected sockets.
sock_address_any address() const
Gets the local address to which the socket is bound.
T check_ret(T ret) const
Checks the value and if less than zero, sets last error.
Definition: socket.h:137
bool get_option(int level, int optname, T *val) const
Gets the value of a socket option.
Definition: socket.h:376
void set_last_error()
Cache the last system error code into this object.
Definition: socket.h:127
Generic socket address.
Definition: sock_address.h:108
static void destroy()
Shuts down the socket library.
socket(socket_t h)
Creates a socket from an existing OS socket handle.
Definition: socket.h:190
bool close_on_err()
Closes the socket without checking for errors or updating the last error.
Definition: socket.h:111
virtual sa_family_t family() const
Gets the network family of the address to which the socket is bound.
Definition: socket.h:266
void clear(int val=0)
Clears the error flag for the object.
Definition: socket.h:306
bool set_option(int level, int optname, const T &val)
Sets the value of a socket option.
Definition: socket.h:407
bool operator!() const
Determines if the socket is closed or in an error state.
Definition: socket.h:244
socket(socket &&sock) noexcept
Move constructor.
Definition: socket.h:196
bool set_option(int level, int optname, const void *optval, socklen_t optlen)
Sets the value of a socket option.
virtual ~socket()
Destructor closes the socket.
Definition: socket.h:203
bool bind(const sock_address &addr)
Binds the socket to the specified address.
bool check_ret_bool(T ret) const
Checks the value and if less than zero, sets last error.
Definition: socket.h:149
socket & operator=(socket &&sock) noexcept
Move assignment.
Definition: socket.h:327
bool set_non_blocking(bool on=true)
Places the socket into or out of non-blocking mode.
bool is_open() const
Determines if the socket is open (valid).
Definition: socket.h:238
socket()
Creates an unconnected (invalid) socket.
Definition: socket.h:183
bool close()
Closes the socket.
Definition: acceptor.h:51
socket clone() const
Creates a new socket that refers to this one.
static socket create(int domain, int type, int protocol=0)
Creates a socket with the specified communications characterics.
int last_error() const
Gets the code for the last errror.
Definition: socket.h:431
socket_t check_socket(socket_t ret) const
Checks the value and if it is not a valid socket, sets last error.
Definition: socket.h:161
static std::string error_str(int errNum)
Gets a string describing the specified error.
Base class for socket objects.
Definition: socket.h:84
bool shutdown(int how=SHUT_RDWR)
Shuts down all or part of the full-duplex connection.
static int get_last_error()
OS-specific means to retrieve the last error from an operation.
std::string last_error_str() const
Gets a string describing the last errror.
Definition: socket.h:437
int socket_t
The OS socket handle.
Definition: socket.h:60
void reset(socket_t h=INVALID_SOCKET)
Replaces the underlying managed socket object.
sock_address_any peer_address() const
Gets the address of the remote peer, if this socket is connected.
socket_t release()
Releases ownership of the underlying socket object.
Definition: socket.h:311
RAII class to initialize and then shut down the library.
Definition: socket.h:470
virtual sa_family_t family() const
Gets the network family of the address.
Definition: sock_address.h:93
socket_t handle() const
Get the underlying OS socket handle.
Definition: socket.h:259
bool get_option(int level, int optname, void *optval, socklen_t *optlen) const
Gets the value of a socket option.
static void initialize()
Initializes the socket (sockpp) library.
Generic address class for sockpp.
const socket_t INVALID_SOCKET
Invalid socket descriptor.
Definition: socket.h:61
bool check_socket_bool(socket_t ret) const
Checks the value and if it is INVALID_SOCKET, sets last error.
Definition: socket.h:174