sockpp
Modern C++ socket library wrapper
datagram_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_datagram_socket_h
48 #define __sockpp_datagram_socket_h
49 
50 #include "sockpp/socket.h"
51 
52 namespace sockpp {
53 
55 
62 class datagram_socket : public socket
63 {
65  using base = socket;
66 
67  // Non-copyable
68  datagram_socket(const datagram_socket&) =delete;
69  datagram_socket& operator=(const datagram_socket&) =delete;
70 
71 protected:
72  static socket_t create_handle(int domain) {
73  return socket_t(::socket(domain, COMM_TYPE, 0));
74  }
75 
76 public:
78  static constexpr int COMM_TYPE = SOCK_DGRAM;
79 
89  explicit datagram_socket(socket_t handle) : base(handle) {}
94  explicit datagram_socket(const sock_address& addr);
100  : base(std::move(other)) {}
107  base::operator=(std::move(rhs));
108  return *this;
109  }
119  bool connect(const sock_address& addr) {
120  return check_ret_bool(::connect(handle(), addr.sockaddr_ptr(),
121  addr.size()));
122  }
123 
124  // ----- I/O -----
125 
134  ssize_t send_to(const void* buf, size_t n, int flags, const sock_address& addr) {
135  #if defined(_WIN32)
136  return check_ret(::sendto(handle(), reinterpret_cast<const char*>(buf), int(n),
137  flags, addr.sockaddr_ptr(), addr.size()));
138  #else
139  return check_ret(::sendto(handle(), buf, n, flags,
140  addr.sockaddr_ptr(), addr.size()));
141  #endif
142  }
150  ssize_t send_to(const std::string& s, int flags, const sock_address& addr) {
151  return send_to(s.data(), s.length(), flags, addr);
152  }
160  ssize_t send_to(const void* buf, size_t n, const sock_address& addr) {
161  return send_to(buf, n, 0, addr);
162  }
169  ssize_t send_to(const std::string& s, const sock_address& addr) {
170  return send_to(s.data(), s.length(), 0, addr);
171  }
180  ssize_t send(const void* buf, size_t n, int flags=0) {
181  #if defined(_WIN32)
182  return check_ret(::send(handle(), reinterpret_cast<const char*>(buf),
183  int(n), flags));
184  #else
185  return check_ret(::send(handle(), buf, n, flags));
186  #endif
187  }
195  ssize_t send(const std::string& s, int flags=0) {
196  return send(s.data(), s.length(), flags);
197  }
207  ssize_t recv_from(void* buf, size_t n, int flags, sock_address* srcAddr=nullptr);
216  ssize_t recv_from(void* buf, size_t n, sock_address* srcAddr=nullptr) {
217  return recv_from(buf, n, 0, srcAddr);
218  }
226  ssize_t recv(void* buf, size_t n, int flags=0) {
227  #if defined(_WIN32)
228  return check_ret(::recv(handle(), reinterpret_cast<char*>(buf),
229  int(n), flags));
230  #else
231  return check_ret(::recv(handle(), buf, n, flags));
232  #endif
233  }
234 };
235 
237 
244 template <typename ADDR>
246 {
248  using base = datagram_socket;
249 
250 public:
252  static constexpr sa_family_t ADDRESS_FAMILY = ADDR::ADDRESS_FAMILY;
254  using addr_t = ADDR;
255 
260  datagram_socket_tmpl() : base(create_handle(ADDRESS_FAMILY)) {}
271  datagram_socket_tmpl(const ADDR& addr) : base(addr) {}
277  : base(std::move(other)) {}
284  base::operator=(std::move(rhs));
285  return *this;
286  }
287 
300  static std::tuple<datagram_socket_tmpl, datagram_socket_tmpl> pair(int protocol=0) {
301  auto pr = base::pair(addr_t::ADDRESS_FAMILY, COMM_TYPE, protocol);
302  return std::make_tuple<datagram_socket_tmpl, datagram_socket_tmpl>(
303  datagram_socket_tmpl{std::get<0>(pr).release()},
304  datagram_socket_tmpl{std::get<1>(pr).release()});
305  }
313  bool bind(const ADDR& addr) { return base::bind(addr); }
323  bool connect(const ADDR& addr) { return base::connect(addr); }
324 
325  // ----- I/O -----
326 
335  ssize_t send_to(const void* buf, size_t n, int flags, const ADDR& addr) {
336  return base::send_to(buf, n, flags, addr);
337  }
345  ssize_t send_to(const std::string& s, int flags, const ADDR& addr) {
346  return base::send_to(s, flags, addr);
347  }
355  ssize_t send_to(const void* buf, size_t n, const ADDR& addr) {
356  return base::send_to(buf, n, 0, addr);
357  }
364  ssize_t send_to(const std::string& s, const ADDR& addr) {
365  return base::send_to(s, addr);
366  }
376  ssize_t recv_from(void* buf, size_t n, int flags, ADDR* srcAddr) {
377  return base::recv_from(buf, n, flags, srcAddr);
378  }
387  ssize_t recv_from(void* buf, size_t n, ADDR* srcAddr=nullptr) {
388  return base::recv_from(buf, n, srcAddr);
389  }
390 };
391 
393 // end namespace sockpp
394 }
395 
396 #endif // __sockpp_datagram_socket_h
397 
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.
ssize_t send_to(const void *buf, size_t n, int flags, const ADDR &addr)
Sends a message to the socket at the specified address.
Definition: datagram_socket.h:335
ssize_t recv_from(void *buf, size_t n, int flags, sock_address *srcAddr=nullptr)
Receives a message on the socket.
T check_ret(T ret) const
Checks the value and if less than zero, sets last error.
Definition: socket.h:137
datagram_socket_tmpl(datagram_socket_tmpl &&other)
Move constructor.
Definition: datagram_socket.h:276
ssize_t send(const void *buf, size_t n, int flags=0)
Sends a message to the socket at the default address.
Definition: datagram_socket.h:180
datagram_socket_tmpl(socket_t handle)
Creates a datagram socket from an existing OS socket handle and claims ownership of the handle...
Definition: datagram_socket.h:266
virtual sockaddr * sockaddr_ptr()=0
Gets a pointer to this object cast to a sockaddr.
ssize_t send_to(const std::string &s, const ADDR &addr)
Sends a string to another socket.
Definition: datagram_socket.h:364
ssize_t send_to(const void *buf, size_t n, const sock_address &addr)
Sends a message to another socket.
Definition: datagram_socket.h:160
bool connect(const ADDR &addr)
Connects the socket to the remote address.
Definition: datagram_socket.h:323
datagram_socket_tmpl(const ADDR &addr)
Creates a UDP socket and binds it to the address.
Definition: datagram_socket.h:271
Base class for datagram sockets.
Definition: datagram_socket.h:245
ssize_t send_to(const std::string &s, int flags, const ADDR &addr)
Sends a string to the socket at the specified address.
Definition: datagram_socket.h:345
ssize_t recv(void *buf, size_t n, int flags=0)
Receives a message on the socket.
Definition: datagram_socket.h:226
Base class for datagram sockets.
Definition: datagram_socket.h:62
ssize_t recv_from(void *buf, size_t n, ADDR *srcAddr=nullptr)
Receives a message on the socket.
Definition: datagram_socket.h:387
datagram_socket(socket_t handle)
Creates a datagram socket from an existing OS socket handle and claims ownership of the handle...
Definition: datagram_socket.h:89
ssize_t send(const std::string &s, int flags=0)
Sends a string to the socket at the default address.
Definition: datagram_socket.h:195
datagram_socket_tmpl & operator=(datagram_socket_tmpl &&rhs)
Move assignment.
Definition: datagram_socket.h:283
bool bind(const sock_address &addr)
Binds the socket to the specified address.
ssize_t recv_from(void *buf, size_t n, int flags, ADDR *srcAddr)
Receives a message on the socket.
Definition: datagram_socket.h:376
ssize_t send_to(const void *buf, size_t n, int flags, const sock_address &addr)
Sends a message to the socket at the specified address.
Definition: datagram_socket.h:134
bool check_ret_bool(T ret) const
Checks the value and if less than zero, sets last error.
Definition: socket.h:149
datagram_socket_tmpl()
Creates an unbound datagram socket.
Definition: datagram_socket.h:260
datagram_socket(datagram_socket &&other)
Move constructor.
Definition: datagram_socket.h:99
static std::tuple< datagram_socket_tmpl, datagram_socket_tmpl > pair(int protocol=0)
Creates a pair of connected stream sockets.
Definition: datagram_socket.h:300
ADDR addr_t
The type of address for the socket.
Definition: datagram_socket.h:254
socket()
Creates an unconnected (invalid) socket.
Definition: socket.h:183
Definition: acceptor.h:51
ssize_t recv_from(void *buf, size_t n, sock_address *srcAddr=nullptr)
Receives a message on the socket.
Definition: datagram_socket.h:216
Base class for socket objects.
Definition: socket.h:84
virtual socklen_t size() const =0
Gets the size of this structure.
int socket_t
The OS socket handle.
Definition: socket.h:60
bool connect(const sock_address &addr)
Connects the socket to the remote address.
Definition: datagram_socket.h:119
socket_t release()
Releases ownership of the underlying socket object.
Definition: socket.h:311
ssize_t send_to(const std::string &s, int flags, const sock_address &addr)
Sends a string to the socket at the specified address.
Definition: datagram_socket.h:150
ssize_t send_to(const std::string &s, const sock_address &addr)
Sends a string to another socket.
Definition: datagram_socket.h:169
ssize_t send_to(const void *buf, size_t n, const ADDR &addr)
Sends a message to another socket.
Definition: datagram_socket.h:355
datagram_socket & operator=(datagram_socket &&rhs)
Move assignment.
Definition: datagram_socket.h:106
Classes for TCP & UDP socket.
socket_t handle() const
Get the underlying OS socket handle.
Definition: socket.h:259
bool bind(const ADDR &addr)
Binds the socket to the local address.
Definition: datagram_socket.h:313
static constexpr int COMM_TYPE
The socket &#39;type&#39; for communications semantics.
Definition: datagram_socket.h:78
datagram_socket()
Creates an uninitialized datagram socket.
Definition: datagram_socket.h:83