Skip to main content

receive_reassemble/
receive_reassemble.rs

1//! Join the PONK multicast group and reassemble incoming frames.
2//!
3//! Run with: `cargo run --example receive_reassemble`
4//!
5//! Then, in another terminal, run the `send_multicast` example.
6
7use std::net::{Ipv4Addr, SocketAddr, UdpSocket};
8
9use ponk_protocol::{DEFAULT_PORT, MULTICAST_ADDR, PonkAssembler};
10
11const RECV_BUFFER_SIZE: usize = 65_536;
12
13fn main() -> std::io::Result<()> {
14    let group = Ipv4Addr::from(MULTICAST_ADDR);
15    let socket = UdpSocket::bind((Ipv4Addr::UNSPECIFIED, DEFAULT_PORT))?;
16    socket.join_multicast_v4(&group, &Ipv4Addr::UNSPECIFIED)?;
17    println!("listening for PONK on {group}:{DEFAULT_PORT} — Ctrl-C to stop");
18
19    // Cap in-progress assemblies so untrusted senders cannot exhaust memory.
20    let mut assembler = PonkAssembler::with_max_assemblies(64);
21    let mut buffer = [0u8; RECV_BUFFER_SIZE];
22
23    loop {
24        let (len, peer): (usize, SocketAddr) = socket.recv_from(&mut buffer)?;
25        match assembler.push_datagram(&buffer[..len], peer) {
26            Ok(Some(frame)) => {
27                let points: usize = frame.paths.iter().map(|p| p.points.len()).sum();
28                println!(
29                    "frame from {:?} (id {}): {} path(s), {} point(s)",
30                    frame.sender_name,
31                    frame.sender_id,
32                    frame.paths.len(),
33                    points,
34                );
35            }
36            Ok(None) => {}
37            Err(error) => eprintln!("malformed datagram from {peer}: {error}"),
38        }
39    }
40}