Skip to content
Snippets Groups Projects
client.rs 3.73 KiB
Newer Older
  • Learn to ignore specific revisions
  • use std::error::Error;
    use std::net::UdpSocket;
    use std::time::{SystemTime, UNIX_EPOCH};
    
    use netem_evaluator::Message;
    use netem_evaluator::NetemParameters;
    
    const TIME_BETWEEN_MESSAGES_IN_MICRO_SECONDS: u64 = 10000;
    const MESSAGES_TO_SEND: u32 = 1000;
    
    fn main() -> Result<(), Box<dyn Error>> {
        let socket = UdpSocket::bind("0.0.0.0:0")?;
        let target = "10.0.0.1:6789";
        socket.connect(target)?;
        let mut id = 0;
    
        // TEST GOAL: find out if there is a difference, between no netem, and netem with 0 delay
        // There is a very small difference of 0.03ms on average
        let mut netem_parameters = NetemParameters::new();
        netem_evaluator::set_network_parameters(netem_parameters.clone());
        send_messages_to_server(&socket, &mut id, MESSAGES_TO_SEND, Some(netem_parameters))?;
    
        netem_evaluator::remove_qdiscs();
        send_messages_to_server(&socket, &mut id, MESSAGES_TO_SEND, None)?;
    
        netem_evaluator::create_qdiscs();
        send_messages_to_server(
            &socket,
            &mut id,
            MESSAGES_TO_SEND,
            Some(NetemParameters::new()),
        )?;
    
        // TEST GOAL: find out how good the delay of netem works
        // The delay is pretty accurate
        netem_parameters = NetemParameters::new().with_delay(1);
        netem_evaluator::set_network_parameters(netem_parameters.clone());
        send_messages_to_server(&socket, &mut id, MESSAGES_TO_SEND, Some(netem_parameters))?;
        netem_parameters = NetemParameters::new().with_delay(2);
        netem_evaluator::set_network_parameters(netem_parameters.clone());
        send_messages_to_server(&socket, &mut id, MESSAGES_TO_SEND, Some(netem_parameters))?;
        netem_parameters = NetemParameters::new().with_delay(4);
        netem_evaluator::set_network_parameters(netem_parameters.clone());
        send_messages_to_server(&socket, &mut id, MESSAGES_TO_SEND, Some(netem_parameters))?;
        netem_parameters = NetemParameters::new().with_delay(10);
        netem_evaluator::set_network_parameters(netem_parameters.clone());
        send_messages_to_server(&socket, &mut id, MESSAGES_TO_SEND, Some(netem_parameters))?;
        netem_parameters = NetemParameters::new().with_delay(20);
        netem_evaluator::set_network_parameters(netem_parameters.clone());
        send_messages_to_server(&socket, &mut id, MESSAGES_TO_SEND, Some(netem_parameters))?;
        netem_parameters = NetemParameters::new().with_delay(50);
        netem_evaluator::set_network_parameters(netem_parameters.clone());
        send_messages_to_server(&socket, &mut id, MESSAGES_TO_SEND, Some(netem_parameters))?;
        netem_parameters = NetemParameters::new().with_delay(100);
        netem_evaluator::set_network_parameters(netem_parameters.clone());
        send_messages_to_server(&socket, &mut id, MESSAGES_TO_SEND, Some(netem_parameters))?;
    
        Ok(())
    }
    
    fn send_messages_to_server(
        socket: &UdpSocket,
        id: &mut u128,
        messages_to_send: u32,
        netem_parameters: Option<NetemParameters>,
    ) -> Result<(), Box<dyn Error>> {
        let mut buffer = [0u8; 1000];
        for _ in 0..messages_to_send {
            *id += 1;
            // Get high-precision timestamp
            // Using SystemTime for monotonic timestamps that are consistent across processes
            let message = Message {
                id: *id,
                timestamp: SystemTime::now().duration_since(UNIX_EPOCH)?.as_nanos(),
                netem_parameters: netem_parameters.clone(),
            };
    
            let mut cursor = std::io::Cursor::new(&mut buffer[..]);
            bincode::serialize_into(&mut cursor, &message)?;
    
            socket.send(&buffer)?;
            println!("{message:?}");
            // println!("{:02x?}", &buffer[0..100]);
    
            buffer.fill(0);
            std::thread::sleep(std::time::Duration::from_micros(
                TIME_BETWEEN_MESSAGES_IN_MICRO_SECONDS,
            ));
        }
    
        std::thread::sleep(std::time::Duration::from_secs(1));
        Ok(())
    }