diffusion/
multicast.rs

1use crate::{Reader, Result, Writer};
2
3use std::net::{Ipv4Addr, SocketAddrV4, UdpSocket};
4
5/// is writer for multicast.
6/// `MulticastWriter` uses the natual UDP packet as message boundary.
7#[derive(Debug)]
8pub struct MulticastWriter {
9    socket: UdpSocket,
10    multicast_addr: SocketAddrV4,
11}
12
13impl MulticastWriter {
14    /// returns a new instance of `MulticastWriter`.
15    /// `addr` is the address the sending socket binds to, and also the address that it sends to.
16    pub fn new(multicast_addr: SocketAddrV4) -> Result<MulticastWriter> {
17        let socket = UdpSocket::bind(&multicast_addr)?;
18        Ok(MulticastWriter {
19            socket,
20            multicast_addr,
21        })
22    }
23}
24
25impl Writer for MulticastWriter {
26    fn write(&mut self, buf: &[u8]) -> Result<()> {
27        self.socket.send_to(buf, &self.multicast_addr)?;
28        Ok(())
29    }
30}
31
32/// is reader for multicast.
33/// Reads the UDP packet multicasted from writer. Each packet is a message.
34#[derive(Debug)]
35pub struct MulticastReader {
36    socket: UdpSocket,
37    buf: Vec<u8>,
38}
39
40impl MulticastReader {
41    /// returns a new instance of `MulticastReader`.
42    /// Binds to `addr`.
43    pub fn new(addr: SocketAddrV4) -> Result<MulticastReader> {
44        let socket = UdpSocket::bind(&addr)?;
45        socket.join_multicast_v4(&addr.ip(), &Ipv4Addr::new(0u8, 0u8, 0u8, 0u8))?;
46        let buf = vec![0u8; 1536usize];
47        Ok(MulticastReader {
48            socket,
49            buf,
50        })
51    }
52}
53
54impl Reader for MulticastReader {
55    fn read(&mut self) -> Result<Option<Vec<u8>>> {
56        let (length, _) = self.socket.recv_from(&mut self.buf)?;
57        let (data, _) = self.buf.split_at(length);
58        Ok(Some(Vec::from(data)))
59    }
60}