pub struct UdpServerQueue {
    pub out: VecDeque<(SocketAddr, Vec<u8>)>,
    /* private fields */
}
Expand description

Type to aid with managing a server mio::net::UdpSocket along with MioPoll

Unlike UdpQueue, this is for sockets that are not connected, so it accepts UDP packets from any address/port, and may send UDP packets to any address/port.

First create the UDP socket, add it to MioPoll, then pass the resulting MioSource to UdpServerQueue::init, which allows this struct to manage the queueing. Your ready handler should call UdpServerQueue::flush when the socket is WRITABLE, and UdpServerQueue::read repeatedly until no more packets are available when the socket is READABLE.

use stakker_mio::{MioPoll, Ready, UdpServerQueue, mio::Interest, mio::net::UdpSocket};
use std::net::{IpAddr, SocketAddr};

fn setup_queue(cx: CX![], miopoll: MioPoll, local_addr: SocketAddr)
    -> std::io::Result<UdpServerQueue>
{
    let sock = UdpSocket::bind(local_addr)?;
    let sock = miopoll.add(sock, Interest::READABLE | Interest::WRITABLE, 10,
                           fwd_to!([cx], udp_ready() as (Ready)))?;
    let mut queue = UdpServerQueue::new();
    queue.init(sock);
    Ok(queue)
}

fn udp_ready(&mut self, cx: CX![], ready: Ready) {
    if ready.is_readable() {
        let mut tmp = [0; 4096];
        loop {
            match self.queue.read(&mut tmp) {
                Err(e) => return fail!(cx, "UDP recv error: {}", e),
                Ok(None) => break,
                Ok(Some((addr, slice))) => {
                    // ... process packet in `slice` from source `addr` ...
                }
            }
        }
    }

    if ready.is_writable() {
        if let Err(e) = self.queue.flush() {
            fail!(cx, "UDP send error: {}", e);
        }
    }
}

Fields§

§out: VecDeque<(SocketAddr, Vec<u8>)>

Output queue. To send, append packets here using out.push_back() or the UdpServerQueue::push call and then call UdpServerQueue::flush. If the OS buffer is full, then you’ll see packets building up here. However unlike TCP, UDP has no mechanism for backpressure, so any buildup should clear quickly as the OS moves the packets out of its own buffers and indicates WRITABLE again.

Implementations§

source§

impl UdpServerQueue

source

pub fn new() -> Self

Create a new empty UdpServerQueue, without any UDP socket currently associated

source

pub fn init(&mut self, socket: MioSource<UdpSocket>)

After adding a socket to the MioPoll instance with MioPoll::add, store the MioSource here to handle the buffering. UdpServerQueue takes care of deregistering the stream on drop. The caller should probably call UdpServerQueue::flush and UdpServerQueue::read soon after this call.

source

pub fn deinit(&mut self)

Discard the current socket if there is one, deregistering it from the MioPoll instance.

source

pub fn push(&mut self, addr: SocketAddr, packet: Vec<u8>)

Add a packet to the queue to send to the given address. You must call UdpServerQueue::flush soon after.

source

pub fn flush(&mut self) -> Result<()>

Flush as many packets out as possible

source

pub fn read<'a>( &mut self, tmp: &'a mut [u8] ) -> Result<Option<(SocketAddr, &'a [u8])>>

Read in a packet, if available. This call is non-blocking. tmp is a scratch buffer used for fetching packets, which should be larger than the largest packet expected. If a packet is too large, it will either be truncated (UNIX) or discarded (Windows). The largest possible UDP packet is just under 64KiB. tmp may be a reference to an array on the stack, or you might wish to keep a temporary buffer permanently allocated somewhere if you need it to be large and avoid the cost of zeroing a buffer regularly.

On reading a packet, Ok(Some((addr, slice))) is returned, where slice is a reference into tmp, and addr is the source SocketAddr. If there is no packet available, Ok(None) is returned. This method must be called repeatedly until it returns Ok(None). Only then will mio be primed to send a new READABLE ready-notification.

Packets are intentionally fetched one at a time, which allows regulating the input rate if that is required, perhaps in combination with stakker::idle!. Since there is no backpressure in UDP, if you allow too much data to build up in the OS queue then the OS may drop packets. However dropping them in the OS queue is more efficient than loading them into memory and having to drop them there.

source

pub fn read_to_vec( &mut self, tmp: &mut [u8] ) -> Result<Option<(SocketAddr, Vec<u8>)>>

Read in a packet, if available. Works as for UdpServerQueue::read, except that the data is copied into a new Vec.

Trait Implementations§

source§

impl Default for UdpServerQueue

source§

fn default() -> UdpServerQueue

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

const: unstable · source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
const: unstable · source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> Any for Twhere T: Any,