homemade udp in rust
udp is simpler than you think
TCP gets all the attention because it's what most applications use. but UDP is where the interesting low-level work happens — game networking, video streaming, DNS, QUIC.
UDP has no handshake, no connection state, no retransmission, no ordering. you send a datagram, it either arrives or it doesn't. that's it.
use std::net::UdpSocket;
fn main() -> std::io::Result<()> {
let socket = UdpSocket::bind("0.0.0.0:8080")?;
let mut buf = [0u8; 65535];
loop {
let (len, src) = socket.recv_from(&mut buf)?;
socket.send_to(&buf[..len], src)?; // echo server
}
}
building reliability on top
if you need reliability over UDP — like QUIC does — you build it yourself. this gives you control over:
- retransmission strategy: exponential backoff vs fixed intervals
- ordering: sequence numbers, reorder buffer size
- congestion control: you choose the algorithm
struct ReliableUdp {
socket: UdpSocket,
send_buf: HashMap<u32, (Vec<u8>, Instant)>,
recv_buf: BTreeMap<u32, Vec<u8>>,
next_seq: u32,
next_ack: u32,
}
where this is useful
game servers use unreliable UDP for position updates — a stale position is useless anyway, so retransmitting it wastes bandwidth. they use reliable UDP only for events that must arrive: kills, item pickups, chat messages.
this split reliability model is impossible with raw TCP. with UDP, it's straightforward.