Skip to main content

BingerUdp

Struct BingerUdp 

Source
pub struct BingerUdp { /* private fields */ }
Expand description

A batch-native UDP socket that automatically selects the most efficient platform syscall for send and receive operations.

§Platform backends

PlatformSend backendRecv backend
Linux (connected)sendmsg with GSOrecvmmsg with GRO
Linux (multi-dest)sendmmsgrecvmmsg
macOSsendmsg_x (via dlsym)recvmsg_x (via dlsym)
WindowsWSASendMsg (via WSAIoctl)WSARecvMsg (via WSAIoctl)
Fallbacksendto (loop)recvfrom (loop)

§Async support

With the default tokio feature, all async methods use Tokio’s readiness-based I/O (tokio::net::UdpSocket::readable / tokio::net::UdpSocket::writable) without busy-looping.

§Example

use binger_udp::{BingerUdp, SendBatch, RecvBatch, Config};

let socket = BingerUdp::from_std(
    std::net::UdpSocket::bind("0.0.0.0:0")?,
    Config::default(),
)?;

let mut send = SendBatch::<32>::new();
send.push(b"hello", "192.168.1.1:8080".parse().unwrap())?;
socket.send_batch(&mut send).await?;

Implementations§

Source§

impl BingerUdp

Source

pub fn from_std(socket: UdpSocket, config: Config) -> Result<Self>

Creates a BingerUdp from a standard std::net::UdpSocket and Config.

The socket is set to non-blocking mode. OS-level buffer sizes specified in the config (SO_SNDBUF, SO_RCVBUF) are applied before constructing the wrapper.

With the default tokio feature, the socket is converted into a tokio::net::UdpSocket for async readiness-based I/O.

This is the primary (and only) way to create a BingerUdp instance.

§Errors

Returns an I/O error if:

  • Setting the socket to non-blocking fails.
  • Setting OS socket buffer sizes fails.
  • Converting to a tokio socket fails (with tokio feature).
§Example
use binger_udp::{BingerUdp, Config};

let socket = BingerUdp::from_std(
    std::net::UdpSocket::bind("0.0.0.0:0").unwrap(),
    Config::default(),
).unwrap();
Source

pub async fn send_batch(&self, batch: &mut SendBatchRaw) -> Result<usize>

Sends all packets in the batch, retrying on WouldBlock.

This is the primary send API. It calls BingerUdp::try_send_batch in a loop, waiting for the socket to become writable whenever the kernel returns WouldBlock.

The batch argument can be a SendBatch<N> or SendBatchRaw (the former dereferences via std::ops::DerefMut).

Returns the total number of packets sent on success (always equal to batch.len() since retries are transparent).

§Errors

Returns the underlying I/O error on failure. WouldBlock is handled internally and never returned to the caller.

Source

pub async fn recv_batch(&self, batch: &mut RecvBatchRaw) -> Result<usize>

Receives a batch of packets, retrying on WouldBlock.

This is the primary receive API. It calls BingerUdp::try_recv_batch in a loop, waiting for the socket to become readable whenever the kernel returns WouldBlock.

The batch argument can be a RecvBatch<N> or RecvBatchRaw (the former dereferences via std::ops::DerefMut).

Returns the number of packets actually received (may be less than batch.capacity()).

§Errors

Returns the underlying I/O error on failure. WouldBlock is handled internally and never returned to the caller.

Source

pub fn try_send_batch(&self, batch: &mut SendBatchRaw) -> Result<usize>

Attempts to send a batch of packets without retrying on WouldBlock.

Unlike BingerUdp::send_batch, this method returns io::ErrorKind::WouldBlock immediately if the socket is not ready for writing. This is useful for integrating with custom event loops or select!-based concurrency.

The batch argument can be a SendBatch<N> or SendBatchRaw.

Returns the number of packets actually sent (may be less than batch.len() on a partial write, or 0 if WouldBlock).

§Errors

Returns the underlying I/O error on failure, including WouldBlock.

Source

pub fn try_recv_batch(&self, batch: &mut RecvBatchRaw) -> Result<usize>

Attempts to receive a batch of packets without retrying on WouldBlock.

Unlike BingerUdp::recv_batch, this method returns io::ErrorKind::WouldBlock immediately if the socket is not ready for reading.

The batch argument can be a RecvBatch<N> or RecvBatchRaw.

Returns the number of packets actually received (0 if WouldBlock).

§Errors

Returns the underlying I/O error on failure, including WouldBlock.

Source

pub async fn send_to(&self, buf: &[u8], addr: SocketAddr) -> Result<usize>

Sends a single UDP datagram to the specified address, retrying on WouldBlock.

This is a convenience wrapper around BingerUdp::send_batch that constructs a single-element batch internally.

§Errors

Returns the underlying I/O error on failure.

§Panics

Panics if the internal single-element batch capacity is exceeded, which should never happen.

Source

pub async fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)>

Receives a single UDP datagram into the buffer, retrying on WouldBlock.

This is a convenience wrapper around BingerUdp::recv_batch that constructs a single-element batch internally.

Returns the number of bytes received and the source address.

§Errors

Returns the underlying I/O error on failure.

Source

pub fn try_send_to(&self, buf: &[u8], addr: SocketAddr) -> Result<usize>

Attempts to send a single UDP datagram without retrying on WouldBlock.

This is a convenience wrapper around BingerUdp::try_send_batch that constructs a single-element batch internally.

§Errors

Returns the underlying I/O error on failure, including WouldBlock.

§Panics

Panics if the internal single-element batch capacity is exceeded, which should never happen.

Source

pub fn connect(&self, addr: SocketAddr) -> Result<()>

Connects the UDP socket to a remote address.

A connected UDP socket can only send to and receive from that address. This is required for GSO (Generic Segmentation Offload) on Linux.

§Errors

Returns the underlying I/O error on failure (e.g., invalid address).

Source

pub fn local_addr(&self) -> Result<SocketAddr>

Returns the local socket address.

§Errors

Returns the underlying IO error on failure.

Source

pub fn ttl(&self) -> Result<u32>

Returns the TTL of the socket.

§Errors

Returns the underlying IO error on failure.

Source

pub fn set_ttl(&self, ttl: u32) -> Result<()>

Sets the TTL of the socket.

§Errors

Returns the underlying IO error on failure.

Source

pub fn as_raw_fd(&self) -> RawFd

Returns the underlying file descriptor (or socket handle on Windows).

On Unix, this is a RawFd (c_int). On Windows, this is a SOCKET (usize).

Use this to pass the socket to low-level system calls or integration with other I/O libraries.

Source

pub fn capabilities(&self) -> PlatformCaps

Returns the PlatformCaps for the current platform and enabled features.

This is a shorthand for calling platform_capabilities() directly.

Source

pub fn recommended_batch_size(&self) -> usize

Returns the recommended batch size based on adaptive batching state.

When adaptive batching is enabled via Config::with_adaptive_batching, this returns the dynamically adjusted batch size (pass true at construction time). The adjustment happens at most every 100 ms:

  • When the WouldBlock rate exceeds 30%, the batch size is halved.
  • When the rate drops below 10%, the batch size is increased by 50%.
  • The batch size is clamped to the range [1, 1024].

If adaptive batching is disabled, returns a fixed default of 32.

§Panics
Source

pub async fn readable(&self) -> Result<()>

Waits until the socket becomes readable.

This is a direct wrapper around tokio::net::UdpSocket::readable(). Use this in tokio::select! to be notified when data is available for BingerUdp::recv_batch or BingerUdp::recv_from.

Only available with the default tokio feature.

§Errors

Returns the underlying I/O error on failure.

Source

pub async fn writable(&self) -> Result<()>

Waits until the socket becomes writable.

This is a direct wrapper around tokio::net::UdpSocket::writable(). Use this in tokio::select! to be notified when the socket can accept data for BingerUdp::send_batch or BingerUdp::send_to.

Only available with the default tokio feature.

§Errors

Returns the underlying I/O error on failure.

Trait Implementations§

Auto Trait Implementations§

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

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

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 T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

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

Performs the conversion.
Source§

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

Source§

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

The type returned in the event of a conversion error.
Source§

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

Performs the conversion.