Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

UDP

UDP 使用 datagram pipeline。它的模型和 TCP 相似,但边界是完整 datagram,不是 byte stream。

Server

UdpServer::bind(addr) 创建 socket server builder。.pipeline(|| ...) 设置 socket-level pipeline factory:

#![allow(unused)]
fn main() {
use rs_netty::{codec::Utf8DatagramCodec, datagram_pipeline, handler, Result, UdpServer};

struct UdpEcho;

#[handler(UdpEcho)]
async fn udp_echo(msg: String) -> Result<String> {
    Ok(format!("echo: {msg}"))
}

let server = UdpServer::bind("127.0.0.1:0")
    .pipeline(|| {
        datagram_pipeline()
            .codec(Utf8DatagramCodec)
            .handler(UdpEcho)
    })
    .start()
    .await?;

server.shutdown();
server.wait().await?;
Ok::<(), rs_netty::Error>(())
}

UdpServerHandle 提供 local_addr()shutdown()wait()

Client

UdpClient::connect(remote_addr) 默认绑定 "0.0.0.0:0"。可以用 .bind(local_addr) 指定本地地址。UdpClientHandle<W> 对默认 remote peer 提供:

  • write(msg)
  • flush()
  • write_and_flush(msg)

也提供显式 peer 版本:

  • write_to(peer_addr, msg)
  • write_to_and_flush(peer_addr, msg)

Socket-Level Pipeline

UDP server 当前只创建一个 socket-level pipeline,不为每个 peer 创建 child pipeline。每个 datagram 处理时都会构造新的 DatagramInfoInboundContextBusinessContextDatagramContextOutboundContext,其中 peer_addr() 是当前 datagram 的来源地址。

如果应用需要 per-peer 状态,请在 handler 中自己维护状态。例如:

#![allow(unused)]
fn main() {
use std::{collections::HashMap, net::SocketAddr};

struct PeerState;

struct StatefulUdp {
    peers: HashMap<SocketAddr, PeerState>,
}
}

Configuration

UDP 使用 UdpSocketConfig

  • read_buffer_capacity: 默认 64 KiB,运行前会 normalize 到至少 max_datagram_size
  • write_buffer_capacity: 默认 8 KiB。
  • max_datagram_size: 默认 64 KiB。
  • outbound_queue_size: 默认 1024。

builder 方法包括:

  • read_buffer_capacity(value)
  • write_buffer_capacity(value)
  • max_datagram_size(value)
  • outbound_queue_size(value)

UDP 当前没有 TCP 的 tcp_nodelay、connection stats 或 idle timeout。

Datagram Write Semantics

DatagramContext::write(msg) 写给当前 datagram peer;write_to(peer, msg) 写给显式 peer。两者都只是暂存到 handler-local outbox。flush*_and_flush 会把 pending datagrams 通过 send_to 发出。

UDP 的 flush acknowledgement 只表示本地 send_to 已完成,不表示对端收到,也不提供顺序、重传或可靠性保证。