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 处理时都会构造新的 DatagramInfo、InboundContext、BusinessContext、DatagramContext 和 OutboundContext,其中 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 已完成,不表示对端收到,也不提供顺序、重传或可靠性保证。