test_retransmits/
test_retransmits.rs

1/// Example demonstrating TCP retransmit tracking
2///
3/// This example shows how retransmits are tracked and reported during TCP tests.
4/// Retransmits will only be visible on Linux systems that support TCP_INFO.
5///
6/// Run a server: cargo run --example test_retransmits server
7/// Run a client: cargo run --example test_retransmits client
8use rperf3::{Client, Config, ProgressEvent, Server};
9use std::time::Duration;
10
11#[tokio::main]
12async fn main() -> Result<(), Box<dyn std::error::Error>> {
13    env_logger::init();
14
15    let args: Vec<String> = std::env::args().collect();
16    let mode = args.get(1).map(|s| s.as_str()).unwrap_or("client");
17
18    match mode {
19        "server" => {
20            println!("Starting TCP server on port 5201...");
21            println!("Retransmits will be shown if they occur during the test.\n");
22
23            let config = Config::server(5201);
24            let server = Server::new(config);
25            server.run().await?;
26        }
27        "client" => {
28            println!("Starting TCP client test (10 seconds)...");
29            println!("Retransmits will be tracked and displayed per interval.\n");
30
31            let config = Config::client("127.0.0.1".to_string(), 5201)
32                .with_duration(Duration::from_secs(10));
33
34            let client = Client::new(config)?.with_callback(|event: ProgressEvent| match event {
35                ProgressEvent::TestStarted => {
36                    println!("Test started");
37                }
38                ProgressEvent::IntervalUpdate {
39                    interval_start,
40                    interval_end,
41                    bits_per_second,
42                    retransmits,
43                    ..
44                } => {
45                    if let Some(retrans) = retransmits {
46                        println!(
47                            "[{:.1}-{:.1}s] {:.2} Mbps  - {} retransmits detected",
48                            interval_start.as_secs_f64(),
49                            interval_end.as_secs_f64(),
50                            bits_per_second / 1_000_000.0,
51                            retrans
52                        );
53                    } else {
54                        println!(
55                            "[{:.1}-{:.1}s] {:.2} Mbps  - no retransmits",
56                            interval_start.as_secs_f64(),
57                            interval_end.as_secs_f64(),
58                            bits_per_second / 1_000_000.0
59                        );
60                    }
61                }
62                ProgressEvent::TestCompleted {
63                    total_bytes,
64                    bits_per_second,
65                    ..
66                } => {
67                    println!("\nTest completed:");
68                    println!("  Total bytes: {}", total_bytes);
69                    println!(
70                        "  Average throughput: {:.2} Mbps",
71                        bits_per_second / 1_000_000.0
72                    );
73                    println!("\nNote: Retransmit tracking is only available on Linux systems.");
74                }
75                ProgressEvent::Error(msg) => {
76                    eprintln!("Error: {}", msg);
77                }
78            });
79
80            client.run().await?;
81        }
82        _ => {
83            eprintln!("Usage: {} [server|client]", args[0]);
84            std::process::exit(1);
85        }
86    }
87
88    Ok(())
89}