2 #ifndef UVCC_HANDLE_UDP__HPP 3 #define UVCC_HANDLE_UDP__HPP 5 #include "uvcc/utility.hpp" 6 #include "uvcc/handle-base.hpp" 7 #include "uvcc/handle-io.hpp" 8 #include "uvcc/loop.hpp" 13 #include <type_traits> 26 friend class handle::uv_interface;
27 friend class handle::instance< udp >;
28 friend class udp_send;
32 using uv_t = ::uv_udp_t;
54 struct properties :
io::properties {};
56 struct uv_interface :
handle::uv_handle_interface,
io::uv_interface
58 std::size_t write_queue_size(
void *_uv_handle)
const noexcept override 59 {
return static_cast< ::uv_udp_t* >(_uv_handle)->send_queue_size; }
61 int read_start(
void *_uv_handle, int64_t _offset)
const noexcept override 63 if (_offset >= 0) instance::from(_uv_handle)->properties().rdoffset = _offset;
64 return ::uv_udp_recv_start(
static_cast< ::uv_udp_t* >(_uv_handle), alloc_cb, recv_cb);
67 int read_stop(
void *_uv_handle)
const noexcept override 68 {
return ::uv_udp_recv_stop(
static_cast< ::uv_udp_t* >(_uv_handle)); }
79 explicit udp(uv_t *_uv_handle) :
io(
static_cast<
io::uv_t* >(_uv_handle)) {}
85 udp(
const udp&) =
default;
86 udp& operator =(
const udp&) =
default;
88 udp(
udp&&)
noexcept =
default;
89 udp& operator =(
udp&&)
noexcept =
default;
97 uv_handle = instance::create();
99 auto uv_ret = ::uv_udp_init_ex(
static_cast< uv::loop::uv_t* >(_loop),
static_cast< uv_t* >(uv_handle), _flags);
100 if (uv_status(uv_ret) < 0)
return;
102 instance::from(uv_handle)->book_loop();
109 uv_handle = instance::create();
111 auto uv_ret = ::uv_udp_init(
static_cast<
uv::
loop::uv_t* >(_loop),
static_cast< uv_t* >(uv_handle));
112 if (uv_status(uv_ret) < 0)
return;
114 instance::from(uv_handle)->book_loop();
116 uv_status(::uv_udp_open(
static_cast< uv_t* >(uv_handle), _socket));
120 template<
typename =
void >
static void alloc_cb(::uv_handle_t*, std::size_t, ::uv_buf_t*);
121 template<
typename =
void >
static void recv_cb(::uv_udp_t*, ssize_t,
const ::uv_buf_t*,
const ::sockaddr*,
unsigned int);
128 std::size_t
send_queue_size()
const noexcept {
return static_cast< uv_t* >(uv_handle)->send_queue_size; }
130 std::size_t
send_queue_count()
const noexcept {
return static_cast< uv_t* >(uv_handle)->send_queue_count; }
139 return uv_status(::uv_udp_set_membership(
140 static_cast< uv_t* >(uv_handle),
141 _multicast_addr, _interface_addr, _membership
147 {
return uv_status(::uv_udp_set_multicast_loop(
static_cast< uv_t* >(uv_handle), _enable)); }
151 {
return uv_status(::uv_udp_set_multicast_ttl(
static_cast< uv_t* >(uv_handle), _value)); }
155 {
return uv_status(::uv_udp_set_multicast_interface(
static_cast< uv_t* >(uv_handle), _interface_addr)); }
159 {
return uv_status(::uv_udp_set_broadcast(
static_cast< uv_t* >(uv_handle), _enable)); }
169 int bind(
const _T_ &_sockaddr,
unsigned int _flags = 0)
noexcept 171 return uv_status(::uv_udp_bind(
static_cast< uv_t* >(uv_handle),
reinterpret_cast<
const ::sockaddr* >(&_sockaddr), _flags));
183 uv_status(::uv_udp_getsockname(
static_cast< uv_t* >(uv_handle),
reinterpret_cast< ::sockaddr* >(&_sockaddr), &z)) >= 0
190 int set_ttl(
int _value)
noexcept {
return uv_status(::uv_udp_set_ttl(
static_cast< uv_t* >(uv_handle), _value)); }
193 int recv_start(
const on_buffer_alloc_t &_alloc_cb,
const on_read_t &_recv_cb, std::size_t _size = 0)
const 206 uv_status(::uv_send_buffer_size(
static_cast<
handle::uv_t* >(uv_handle), (
int*)&v));
211 void send_buffer_size(
unsigned int _value)
noexcept { uv_status(::uv_send_buffer_size(
static_cast<
handle::uv_t* >(uv_handle), (
int*)&_value)); }
218 uv_status(::uv_recv_buffer_size(
static_cast<
handle::uv_t* >(uv_handle), (
int*)&v));
223 void recv_buffer_size(
unsigned int _value)
noexcept { uv_status(::uv_recv_buffer_size(
static_cast<
handle::uv_t* >(uv_handle), (
int*)&_value)); }
227 explicit operator
const uv_t*()
const noexcept {
return static_cast<
const uv_t* >(uv_handle); }
228 explicit operator uv_t*()
noexcept {
return static_cast< uv_t* >(uv_handle); }
232 void udp::alloc_cb(::uv_handle_t *_uv_handle, std::size_t _suggested_size, ::uv_buf_t *_uv_buf)
233 { io_alloc_cb(_uv_handle, _suggested_size, _uv_buf); }
236 void udp::recv_cb(::uv_udp_t *_uv_handle, ssize_t _nread,
const ::uv_buf_t *_uv_buf,
const ::sockaddr *_sockaddr,
unsigned int _flags)
238 io_info supplemental_data = { _sockaddr, _flags };
239 io_read_cb(_uv_handle, _nread, _uv_buf, &supplemental_data);
Namespace for all uvcc definitions.
int set_broadcast(bool _enable) noexcept
Set broadcast on or off.
int recv_start(std::size_t _size=0) const
Idem.
int set_multicast_membership(const char *_multicast_addr, const char *_interface_addr, ::uv_membership _membership) noexcept
Set membership for a multicast address.
int read_start(const on_buffer_alloc_t &_alloc_cb, const on_read_t &_read_cb, std::size_t _size=0, int64_t _offset=-1) const
Start reading incoming data from the I/O endpoint with provided input buffer allocation callback (_al...
const ::sockaddr * peer
The address of the remote peer. Can be nullptr. The pointer is valid for the duration of the callback...
::uv_os_sock_t socket() const noexcept
Get the platform dependent socket descriptor. The alias for handle::fileno().
std::size_t send_queue_count() const noexcept
Number of send requests currently in the queue awaiting to be processed.
int read_stop() const
Stop reading data from the I/O endpoint.
The base class for the libuv handles.
unsigned int flags
One or more or’ed uv_udp_flags constants.
void recv_buffer_size(unsigned int _value) noexcept
Set the size of the receive buffer that the operating system uses for the socket. ...
int set_multicast_loop(bool _enable) noexcept
Set IP multicast loop flag. Makes multicast packets loop back to local sockets.
int recv_start(const on_buffer_alloc_t &_alloc_cb, const on_read_t &_recv_cb, std::size_t _size=0) const
Alias for io::read_start().
std::size_t send_queue_size() const noexcept
Number of bytes queued for sending. This field strictly shows how much information is currently queue...
int set_multicast_interface(const char *_interface_addr) noexcept
Set the multicast interface to send or receive data on.
unsigned int send_buffer_size() const noexcept
Get the size of the send buffer that the operating system uses for the socket.
int recv_stop() const
Alias for io::read_stop().
The I/O event loop class.
The base class for handles representing I/O endpoints: a file, TCP/UDP socket, pipe, TTY.
udp(uv::loop &_loop, unsigned int _flags=AF_UNSPEC)
unsigned int recv_buffer_size() const noexcept
Get the size of the receive buffer that the operating system uses for the socket. ...
void send_buffer_size(unsigned int _value) noexcept
Set the size of the send buffer that the operating system uses for the socket.
Supplemental data passed as the last argument to io::on_read_t callback function called by recv_start...
int set_ttl(int _value) noexcept
Set the time to live value.
int bind(const _T_ &_sockaddr, unsigned int _flags=0) noexcept
udp(uv::loop &_loop, ::uv_os_sock_t _socket)
bool getsockname(_T_ &_sockaddr) const noexcept
Get the local address and port which this handle is bound to.
int read_start(std::size_t _size=0, int64_t _offset=-1) const
Start reading incoming data from the I/O endpoint.
int set_multicast_ttl(int _value) noexcept
Set the multicast TTL value.