Config

Struct Config 

Source
pub struct Config {
    pub mode: Mode,
    pub protocol: Protocol,
    pub port: u16,
    pub server_addr: Option<String>,
    pub bind_addr: Option<IpAddr>,
    pub duration: Duration,
    pub bandwidth: Option<u64>,
    pub buffer_size: usize,
    pub parallel: usize,
    pub reverse: bool,
    pub json: bool,
    pub interval: Duration,
}
Expand description

Configuration for rperf3 network performance tests.

This structure holds all configuration parameters for both client and server modes. Use the builder pattern methods to customize the configuration.

§Examples

§Basic TCP Client

use rperf3::Config;
use std::time::Duration;

let config = Config::client("192.168.1.100".to_string(), 5201)
    .with_duration(Duration::from_secs(30))
    .with_buffer_size(256 * 1024); // 256 KB buffer

§UDP Client with Bandwidth Limit

use rperf3::{Config, Protocol};
use std::time::Duration;

let config = Config::client("192.168.1.100".to_string(), 5201)
    .with_protocol(Protocol::Udp)
    .with_bandwidth(100_000_000) // 100 Mbps
    .with_duration(Duration::from_secs(10));

§Server Configuration

use rperf3::Config;

let config = Config::server(5201);

§Reverse Mode Test

use rperf3::Config;
use std::time::Duration;

// Server sends data, client receives
let config = Config::client("192.168.1.100".to_string(), 5201)
    .with_reverse(true)
    .with_duration(Duration::from_secs(10));

Fields§

§mode: Mode

Server mode or client mode

§protocol: Protocol

Protocol to use (TCP or UDP)

§port: u16

Port number to use

§server_addr: Option<String>

Server address (for client mode)

§bind_addr: Option<IpAddr>

Bind address (for server mode)

§duration: Duration

Test duration in seconds

§bandwidth: Option<u64>

Target bandwidth in bits per second (for UDP)

§buffer_size: usize

Buffer size in bytes

§parallel: usize

Number of parallel streams

§reverse: bool

Reverse mode (server sends, client receives)

§json: bool

Output in JSON format

§interval: Duration

Interval for periodic bandwidth reports in seconds

Implementations§

Source§

impl Config

Source

pub fn new() -> Self

Creates a new configuration with default values.

This is equivalent to calling Config::default(). The default configuration is set up for client mode with TCP protocol.

§Examples
use rperf3::Config;

let config = Config::new();
assert_eq!(config.port, 5201);
Source

pub fn server(port: u16) -> Self

Creates a new server configuration.

Sets up the configuration for server mode, which listens for incoming connections on the specified port.

§Arguments
  • port - The port number to listen on (typically 5201)
§Examples
use rperf3::Config;

let config = Config::server(5201);
Examples found in repository?
examples/server.rs (line 9)
4async fn main() -> Result<(), Box<dyn std::error::Error>> {
5    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
6
7    println!("Starting rperf3 server on port 5201...");
8
9    let config = Config::server(5201).with_protocol(Protocol::Tcp);
10
11    let server = Server::new(config);
12    server.run().await?;
13
14    Ok(())
15}
More examples
Hide additional examples
examples/cancellable_test.rs (line 34)
30async fn run_server() -> Result<(), Box<dyn std::error::Error>> {
31    println!("Starting TCP server on port 5201...");
32    println!("Press Ctrl+C to stop the server gracefully.\n");
33
34    let config = Config::server(5201);
35    let server = Server::new(config);
36
37    // Clone the cancellation token to handle CTRL+C
38    let cancel_token = server.cancellation_token().clone();
39
40    // Set up CTRL+C handler
41    tokio::spawn(async move {
42        tokio::signal::ctrl_c()
43            .await
44            .expect("Failed to listen for CTRL+C");
45        println!("\nReceived CTRL+C, shutting down server gracefully...");
46        cancel_token.cancel();
47    });
48
49    server.run().await?;
50    println!("Server stopped.");
51    Ok(())
52}
examples/tcp_nodelay_test.rs (line 29)
17async fn main() -> Result<(), Box<dyn std::error::Error>> {
18    // Initialize logging
19    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
20
21    println!("TCP Socket Optimization Demo");
22    println!("============================\n");
23    println!("This demo tests TCP with:");
24    println!("- TCP_NODELAY enabled (Nagle's algorithm disabled)");
25    println!("- 256KB send/receive buffers");
26    println!("- Expected 10-20% improvement over default settings\n");
27
28    // Start server in background
29    let server_config = Config::server(5201).with_protocol(Protocol::Tcp);
30    let server = Server::new(server_config);
31
32    // Run server in background task
33    tokio::spawn(async move {
34        if let Err(e) = server.run().await {
35            eprintln!("Server error: {}", e);
36        }
37    });
38
39    // Give server time to start
40    time::sleep(Duration::from_millis(100)).await;
41
42    println!("Starting TCP test (5 seconds)...\n");
43
44    // Run client test
45    let client_config = Config::client("127.0.0.1".to_string(), 5201)
46        .with_protocol(Protocol::Tcp)
47        .with_duration(Duration::from_secs(5))
48        .with_interval(Duration::from_secs(1));
49
50    let client = Client::new(client_config)?;
51    client.run().await?;
52
53    // Get measurements
54    let measurements = client.get_measurements();
55    let total_bytes = measurements.total_bytes_sent + measurements.total_bytes_received;
56    let bits_per_second = measurements.total_bits_per_second();
57
58    println!("\n=== Results ===");
59    println!(
60        "Total transferred: {:.2} MB",
61        total_bytes as f64 / 1_000_000.0
62    );
63    println!("Throughput: {:.2} Mbps", bits_per_second / 1_000_000.0);
64    println!("\nSocket optimizations applied:");
65    println!("✓ TCP_NODELAY: enabled");
66    println!("✓ Send buffer: 256KB");
67    println!("✓ Recv buffer: 256KB");
68
69    Ok(())
70}
examples/test_retransmits.rs (line 23)
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}
Source

pub fn client(server_addr: String, port: u16) -> Self

Creates a new client configuration.

Sets up the configuration for client mode, which connects to a server at the specified address and port.

§Arguments
  • server_addr - The IP address or hostname of the server
  • port - The port number to connect to (typically 5201)
§Examples
use rperf3::Config;

let config = Config::client("192.168.1.100".to_string(), 5201);
Examples found in repository?
examples/test_json_output.rs (line 8)
5async fn main() -> Result<(), Box<dyn std::error::Error>> {
6    env_logger::init();
7
8    let config = Config::client("127.0.0.1".to_string(), 5201)
9        .with_duration(Duration::from_secs(3))
10        .with_json(true);
11
12    let client = Client::new(config)?;
13
14    match client.run().await {
15        Ok(_) => println!("\nTest completed successfully"),
16        Err(e) => eprintln!("\nError: {}", e),
17    }
18
19    Ok(())
20}
More examples
Hide additional examples
examples/client.rs (line 10)
5async fn main() -> Result<(), Box<dyn std::error::Error>> {
6    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
7
8    println!("Connecting to rperf3 server at 127.0.0.1:5201...");
9
10    let config = Config::client("127.0.0.1".to_string(), 5201)
11        .with_protocol(Protocol::Tcp)
12        .with_duration(Duration::from_secs(10))
13        .with_buffer_size(128 * 1024);
14
15    let client = Client::new(config)?;
16    client.run().await?;
17
18    let measurements = client.get_measurements();
19    println!(
20        "\nFinal Results: {:.2} Mbps",
21        measurements.total_bits_per_second() / 1_000_000.0
22    );
23
24    Ok(())
25}
examples/udp_client.rs (line 10)
5async fn main() -> Result<(), Box<dyn std::error::Error>> {
6    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
7
8    println!("Running UDP test with 50 Mbps target bandwidth...");
9
10    let config = Config::client("127.0.0.1".to_string(), 5201)
11        .with_protocol(Protocol::Udp)
12        .with_duration(Duration::from_secs(10))
13        .with_bandwidth(50 * 1_000_000) // 50 Mbps
14        .with_buffer_size(1024);
15
16    let client = Client::new(config)?;
17    client.run().await?;
18
19    let measurements = client.get_measurements();
20    println!(
21        "\nFinal Results: {:.2} Mbps",
22        measurements.total_bits_per_second() / 1_000_000.0
23    );
24
25    Ok(())
26}
examples/client_with_callback.rs (line 56)
49async fn main() -> Result<(), Box<dyn std::error::Error>> {
50    env_logger::init();
51
52    println!("rperf3 Client with Callback Example");
53    println!("====================================\n");
54
55    // Configure the test
56    let config = Config::client("127.0.0.1".to_string(), 5201)
57        .with_protocol(Protocol::Tcp)
58        .with_duration(Duration::from_secs(10))
59        .with_buffer_size(128 * 1024)
60        .with_interval(Duration::from_secs(2)); // Report every 2 seconds
61
62    // Create client with custom callback
63    let client = Client::new(config)?.with_callback(MyProgressCallback);
64
65    println!("Connecting to server at 127.0.0.1:5201...\n");
66
67    // Run the test (callback will be invoked during execution)
68    client.run().await?;
69
70    // Get final measurements
71    let measurements = client.get_measurements();
72    println!("\n📈 Final Statistics:");
73    println!("   Total bytes: {}", measurements.total_bytes_sent);
74    println!(
75        "   Duration: {:.2}s",
76        measurements.total_duration.as_secs_f64()
77    );
78    println!(
79        "   Average bandwidth: {:.2} Mbps",
80        measurements.total_bits_per_second() / 1_000_000.0
81    );
82
83    Ok(())
84}
examples/tcp_nodelay_test.rs (line 45)
17async fn main() -> Result<(), Box<dyn std::error::Error>> {
18    // Initialize logging
19    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
20
21    println!("TCP Socket Optimization Demo");
22    println!("============================\n");
23    println!("This demo tests TCP with:");
24    println!("- TCP_NODELAY enabled (Nagle's algorithm disabled)");
25    println!("- 256KB send/receive buffers");
26    println!("- Expected 10-20% improvement over default settings\n");
27
28    // Start server in background
29    let server_config = Config::server(5201).with_protocol(Protocol::Tcp);
30    let server = Server::new(server_config);
31
32    // Run server in background task
33    tokio::spawn(async move {
34        if let Err(e) = server.run().await {
35            eprintln!("Server error: {}", e);
36        }
37    });
38
39    // Give server time to start
40    time::sleep(Duration::from_millis(100)).await;
41
42    println!("Starting TCP test (5 seconds)...\n");
43
44    // Run client test
45    let client_config = Config::client("127.0.0.1".to_string(), 5201)
46        .with_protocol(Protocol::Tcp)
47        .with_duration(Duration::from_secs(5))
48        .with_interval(Duration::from_secs(1));
49
50    let client = Client::new(client_config)?;
51    client.run().await?;
52
53    // Get measurements
54    let measurements = client.get_measurements();
55    let total_bytes = measurements.total_bytes_sent + measurements.total_bytes_received;
56    let bits_per_second = measurements.total_bits_per_second();
57
58    println!("\n=== Results ===");
59    println!(
60        "Total transferred: {:.2} MB",
61        total_bytes as f64 / 1_000_000.0
62    );
63    println!("Throughput: {:.2} Mbps", bits_per_second / 1_000_000.0);
64    println!("\nSocket optimizations applied:");
65    println!("✓ TCP_NODELAY: enabled");
66    println!("✓ Send buffer: 256KB");
67    println!("✓ Recv buffer: 256KB");
68
69    Ok(())
70}
examples/udp_buffer_test.rs (line 36)
20async fn main() -> Result<(), Box<dyn std::error::Error>> {
21    // Initialize logging
22    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
23
24    println!("UDP Socket Optimization Demo");
25    println!("============================\n");
26    println!("This demo tests UDP with:");
27    println!("- 2MB send/receive buffers");
28    println!("- Improved burst handling");
29    println!("- Expected 10-20% improvement with reduced packet loss\n");
30    println!("Note: Make sure the server is running first:");
31    println!("  cargo run --release -- -s -p 5201\n");
32
33    println!("Starting UDP test (5 seconds, 100 Mbps)...\n");
34
35    // Run client test with bandwidth limiting
36    let client_config = Config::client("127.0.0.1".to_string(), 5201)
37        .with_protocol(Protocol::Udp)
38        .with_duration(Duration::from_secs(5))
39        .with_interval(Duration::from_secs(1))
40        .with_bandwidth(100_000_000); // 100 Mbps
41
42    let client = Client::new(client_config)?;
43    client.run().await?;
44
45    // Get measurements
46    let measurements = client.get_measurements();
47    let total_bytes = measurements.total_bytes_sent + measurements.total_bytes_received;
48    let bits_per_second = measurements.total_bits_per_second();
49    let packet_loss = if measurements.total_packets > 0 {
50        (measurements.lost_packets as f64 / measurements.total_packets as f64) * 100.0
51    } else {
52        0.0
53    };
54
55    println!("\n=== Results ===");
56    println!(
57        "Total transferred: {:.2} MB",
58        total_bytes as f64 / 1_000_000.0
59    );
60    println!("Throughput: {:.2} Mbps", bits_per_second / 1_000_000.0);
61    println!("Packet loss: {:.2}%", packet_loss);
62    println!("\nSocket optimizations applied:");
63    println!("✓ Send buffer: 2MB");
64    println!("✓ Recv buffer: 2MB");
65    println!("✓ Reduced packet loss with larger buffers");
66
67    Ok(())
68}
Source

pub fn with_protocol(self, protocol: Protocol) -> Self

Sets the protocol to use for the test.

§Arguments
  • protocol - Either Protocol::Tcp or Protocol::Udp
§Examples
use rperf3::{Config, Protocol};

let config = Config::client("127.0.0.1".to_string(), 5201)
    .with_protocol(Protocol::Udp);
Examples found in repository?
examples/server.rs (line 9)
4async fn main() -> Result<(), Box<dyn std::error::Error>> {
5    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
6
7    println!("Starting rperf3 server on port 5201...");
8
9    let config = Config::server(5201).with_protocol(Protocol::Tcp);
10
11    let server = Server::new(config);
12    server.run().await?;
13
14    Ok(())
15}
More examples
Hide additional examples
examples/client.rs (line 11)
5async fn main() -> Result<(), Box<dyn std::error::Error>> {
6    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
7
8    println!("Connecting to rperf3 server at 127.0.0.1:5201...");
9
10    let config = Config::client("127.0.0.1".to_string(), 5201)
11        .with_protocol(Protocol::Tcp)
12        .with_duration(Duration::from_secs(10))
13        .with_buffer_size(128 * 1024);
14
15    let client = Client::new(config)?;
16    client.run().await?;
17
18    let measurements = client.get_measurements();
19    println!(
20        "\nFinal Results: {:.2} Mbps",
21        measurements.total_bits_per_second() / 1_000_000.0
22    );
23
24    Ok(())
25}
examples/udp_client.rs (line 11)
5async fn main() -> Result<(), Box<dyn std::error::Error>> {
6    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
7
8    println!("Running UDP test with 50 Mbps target bandwidth...");
9
10    let config = Config::client("127.0.0.1".to_string(), 5201)
11        .with_protocol(Protocol::Udp)
12        .with_duration(Duration::from_secs(10))
13        .with_bandwidth(50 * 1_000_000) // 50 Mbps
14        .with_buffer_size(1024);
15
16    let client = Client::new(config)?;
17    client.run().await?;
18
19    let measurements = client.get_measurements();
20    println!(
21        "\nFinal Results: {:.2} Mbps",
22        measurements.total_bits_per_second() / 1_000_000.0
23    );
24
25    Ok(())
26}
examples/client_with_callback.rs (line 57)
49async fn main() -> Result<(), Box<dyn std::error::Error>> {
50    env_logger::init();
51
52    println!("rperf3 Client with Callback Example");
53    println!("====================================\n");
54
55    // Configure the test
56    let config = Config::client("127.0.0.1".to_string(), 5201)
57        .with_protocol(Protocol::Tcp)
58        .with_duration(Duration::from_secs(10))
59        .with_buffer_size(128 * 1024)
60        .with_interval(Duration::from_secs(2)); // Report every 2 seconds
61
62    // Create client with custom callback
63    let client = Client::new(config)?.with_callback(MyProgressCallback);
64
65    println!("Connecting to server at 127.0.0.1:5201...\n");
66
67    // Run the test (callback will be invoked during execution)
68    client.run().await?;
69
70    // Get final measurements
71    let measurements = client.get_measurements();
72    println!("\n📈 Final Statistics:");
73    println!("   Total bytes: {}", measurements.total_bytes_sent);
74    println!(
75        "   Duration: {:.2}s",
76        measurements.total_duration.as_secs_f64()
77    );
78    println!(
79        "   Average bandwidth: {:.2} Mbps",
80        measurements.total_bits_per_second() / 1_000_000.0
81    );
82
83    Ok(())
84}
examples/tcp_nodelay_test.rs (line 29)
17async fn main() -> Result<(), Box<dyn std::error::Error>> {
18    // Initialize logging
19    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
20
21    println!("TCP Socket Optimization Demo");
22    println!("============================\n");
23    println!("This demo tests TCP with:");
24    println!("- TCP_NODELAY enabled (Nagle's algorithm disabled)");
25    println!("- 256KB send/receive buffers");
26    println!("- Expected 10-20% improvement over default settings\n");
27
28    // Start server in background
29    let server_config = Config::server(5201).with_protocol(Protocol::Tcp);
30    let server = Server::new(server_config);
31
32    // Run server in background task
33    tokio::spawn(async move {
34        if let Err(e) = server.run().await {
35            eprintln!("Server error: {}", e);
36        }
37    });
38
39    // Give server time to start
40    time::sleep(Duration::from_millis(100)).await;
41
42    println!("Starting TCP test (5 seconds)...\n");
43
44    // Run client test
45    let client_config = Config::client("127.0.0.1".to_string(), 5201)
46        .with_protocol(Protocol::Tcp)
47        .with_duration(Duration::from_secs(5))
48        .with_interval(Duration::from_secs(1));
49
50    let client = Client::new(client_config)?;
51    client.run().await?;
52
53    // Get measurements
54    let measurements = client.get_measurements();
55    let total_bytes = measurements.total_bytes_sent + measurements.total_bytes_received;
56    let bits_per_second = measurements.total_bits_per_second();
57
58    println!("\n=== Results ===");
59    println!(
60        "Total transferred: {:.2} MB",
61        total_bytes as f64 / 1_000_000.0
62    );
63    println!("Throughput: {:.2} Mbps", bits_per_second / 1_000_000.0);
64    println!("\nSocket optimizations applied:");
65    println!("✓ TCP_NODELAY: enabled");
66    println!("✓ Send buffer: 256KB");
67    println!("✓ Recv buffer: 256KB");
68
69    Ok(())
70}
examples/udp_buffer_test.rs (line 37)
20async fn main() -> Result<(), Box<dyn std::error::Error>> {
21    // Initialize logging
22    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
23
24    println!("UDP Socket Optimization Demo");
25    println!("============================\n");
26    println!("This demo tests UDP with:");
27    println!("- 2MB send/receive buffers");
28    println!("- Improved burst handling");
29    println!("- Expected 10-20% improvement with reduced packet loss\n");
30    println!("Note: Make sure the server is running first:");
31    println!("  cargo run --release -- -s -p 5201\n");
32
33    println!("Starting UDP test (5 seconds, 100 Mbps)...\n");
34
35    // Run client test with bandwidth limiting
36    let client_config = Config::client("127.0.0.1".to_string(), 5201)
37        .with_protocol(Protocol::Udp)
38        .with_duration(Duration::from_secs(5))
39        .with_interval(Duration::from_secs(1))
40        .with_bandwidth(100_000_000); // 100 Mbps
41
42    let client = Client::new(client_config)?;
43    client.run().await?;
44
45    // Get measurements
46    let measurements = client.get_measurements();
47    let total_bytes = measurements.total_bytes_sent + measurements.total_bytes_received;
48    let bits_per_second = measurements.total_bits_per_second();
49    let packet_loss = if measurements.total_packets > 0 {
50        (measurements.lost_packets as f64 / measurements.total_packets as f64) * 100.0
51    } else {
52        0.0
53    };
54
55    println!("\n=== Results ===");
56    println!(
57        "Total transferred: {:.2} MB",
58        total_bytes as f64 / 1_000_000.0
59    );
60    println!("Throughput: {:.2} Mbps", bits_per_second / 1_000_000.0);
61    println!("Packet loss: {:.2}%", packet_loss);
62    println!("\nSocket optimizations applied:");
63    println!("✓ Send buffer: 2MB");
64    println!("✓ Recv buffer: 2MB");
65    println!("✓ Reduced packet loss with larger buffers");
66
67    Ok(())
68}
Source

pub fn with_duration(self, duration: Duration) -> Self

Sets the test duration.

§Arguments
  • duration - How long the test should run
§Examples
use rperf3::Config;
use std::time::Duration;

let config = Config::client("127.0.0.1".to_string(), 5201)
    .with_duration(Duration::from_secs(30));
Examples found in repository?
examples/test_json_output.rs (line 9)
5async fn main() -> Result<(), Box<dyn std::error::Error>> {
6    env_logger::init();
7
8    let config = Config::client("127.0.0.1".to_string(), 5201)
9        .with_duration(Duration::from_secs(3))
10        .with_json(true);
11
12    let client = Client::new(config)?;
13
14    match client.run().await {
15        Ok(_) => println!("\nTest completed successfully"),
16        Err(e) => eprintln!("\nError: {}", e),
17    }
18
19    Ok(())
20}
More examples
Hide additional examples
examples/client.rs (line 12)
5async fn main() -> Result<(), Box<dyn std::error::Error>> {
6    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
7
8    println!("Connecting to rperf3 server at 127.0.0.1:5201...");
9
10    let config = Config::client("127.0.0.1".to_string(), 5201)
11        .with_protocol(Protocol::Tcp)
12        .with_duration(Duration::from_secs(10))
13        .with_buffer_size(128 * 1024);
14
15    let client = Client::new(config)?;
16    client.run().await?;
17
18    let measurements = client.get_measurements();
19    println!(
20        "\nFinal Results: {:.2} Mbps",
21        measurements.total_bits_per_second() / 1_000_000.0
22    );
23
24    Ok(())
25}
examples/udp_client.rs (line 12)
5async fn main() -> Result<(), Box<dyn std::error::Error>> {
6    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
7
8    println!("Running UDP test with 50 Mbps target bandwidth...");
9
10    let config = Config::client("127.0.0.1".to_string(), 5201)
11        .with_protocol(Protocol::Udp)
12        .with_duration(Duration::from_secs(10))
13        .with_bandwidth(50 * 1_000_000) // 50 Mbps
14        .with_buffer_size(1024);
15
16    let client = Client::new(config)?;
17    client.run().await?;
18
19    let measurements = client.get_measurements();
20    println!(
21        "\nFinal Results: {:.2} Mbps",
22        measurements.total_bits_per_second() / 1_000_000.0
23    );
24
25    Ok(())
26}
examples/client_with_callback.rs (line 58)
49async fn main() -> Result<(), Box<dyn std::error::Error>> {
50    env_logger::init();
51
52    println!("rperf3 Client with Callback Example");
53    println!("====================================\n");
54
55    // Configure the test
56    let config = Config::client("127.0.0.1".to_string(), 5201)
57        .with_protocol(Protocol::Tcp)
58        .with_duration(Duration::from_secs(10))
59        .with_buffer_size(128 * 1024)
60        .with_interval(Duration::from_secs(2)); // Report every 2 seconds
61
62    // Create client with custom callback
63    let client = Client::new(config)?.with_callback(MyProgressCallback);
64
65    println!("Connecting to server at 127.0.0.1:5201...\n");
66
67    // Run the test (callback will be invoked during execution)
68    client.run().await?;
69
70    // Get final measurements
71    let measurements = client.get_measurements();
72    println!("\n📈 Final Statistics:");
73    println!("   Total bytes: {}", measurements.total_bytes_sent);
74    println!(
75        "   Duration: {:.2}s",
76        measurements.total_duration.as_secs_f64()
77    );
78    println!(
79        "   Average bandwidth: {:.2} Mbps",
80        measurements.total_bits_per_second() / 1_000_000.0
81    );
82
83    Ok(())
84}
examples/tcp_nodelay_test.rs (line 47)
17async fn main() -> Result<(), Box<dyn std::error::Error>> {
18    // Initialize logging
19    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
20
21    println!("TCP Socket Optimization Demo");
22    println!("============================\n");
23    println!("This demo tests TCP with:");
24    println!("- TCP_NODELAY enabled (Nagle's algorithm disabled)");
25    println!("- 256KB send/receive buffers");
26    println!("- Expected 10-20% improvement over default settings\n");
27
28    // Start server in background
29    let server_config = Config::server(5201).with_protocol(Protocol::Tcp);
30    let server = Server::new(server_config);
31
32    // Run server in background task
33    tokio::spawn(async move {
34        if let Err(e) = server.run().await {
35            eprintln!("Server error: {}", e);
36        }
37    });
38
39    // Give server time to start
40    time::sleep(Duration::from_millis(100)).await;
41
42    println!("Starting TCP test (5 seconds)...\n");
43
44    // Run client test
45    let client_config = Config::client("127.0.0.1".to_string(), 5201)
46        .with_protocol(Protocol::Tcp)
47        .with_duration(Duration::from_secs(5))
48        .with_interval(Duration::from_secs(1));
49
50    let client = Client::new(client_config)?;
51    client.run().await?;
52
53    // Get measurements
54    let measurements = client.get_measurements();
55    let total_bytes = measurements.total_bytes_sent + measurements.total_bytes_received;
56    let bits_per_second = measurements.total_bits_per_second();
57
58    println!("\n=== Results ===");
59    println!(
60        "Total transferred: {:.2} MB",
61        total_bytes as f64 / 1_000_000.0
62    );
63    println!("Throughput: {:.2} Mbps", bits_per_second / 1_000_000.0);
64    println!("\nSocket optimizations applied:");
65    println!("✓ TCP_NODELAY: enabled");
66    println!("✓ Send buffer: 256KB");
67    println!("✓ Recv buffer: 256KB");
68
69    Ok(())
70}
examples/udp_buffer_test.rs (line 38)
20async fn main() -> Result<(), Box<dyn std::error::Error>> {
21    // Initialize logging
22    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
23
24    println!("UDP Socket Optimization Demo");
25    println!("============================\n");
26    println!("This demo tests UDP with:");
27    println!("- 2MB send/receive buffers");
28    println!("- Improved burst handling");
29    println!("- Expected 10-20% improvement with reduced packet loss\n");
30    println!("Note: Make sure the server is running first:");
31    println!("  cargo run --release -- -s -p 5201\n");
32
33    println!("Starting UDP test (5 seconds, 100 Mbps)...\n");
34
35    // Run client test with bandwidth limiting
36    let client_config = Config::client("127.0.0.1".to_string(), 5201)
37        .with_protocol(Protocol::Udp)
38        .with_duration(Duration::from_secs(5))
39        .with_interval(Duration::from_secs(1))
40        .with_bandwidth(100_000_000); // 100 Mbps
41
42    let client = Client::new(client_config)?;
43    client.run().await?;
44
45    // Get measurements
46    let measurements = client.get_measurements();
47    let total_bytes = measurements.total_bytes_sent + measurements.total_bytes_received;
48    let bits_per_second = measurements.total_bits_per_second();
49    let packet_loss = if measurements.total_packets > 0 {
50        (measurements.lost_packets as f64 / measurements.total_packets as f64) * 100.0
51    } else {
52        0.0
53    };
54
55    println!("\n=== Results ===");
56    println!(
57        "Total transferred: {:.2} MB",
58        total_bytes as f64 / 1_000_000.0
59    );
60    println!("Throughput: {:.2} Mbps", bits_per_second / 1_000_000.0);
61    println!("Packet loss: {:.2}%", packet_loss);
62    println!("\nSocket optimizations applied:");
63    println!("✓ Send buffer: 2MB");
64    println!("✓ Recv buffer: 2MB");
65    println!("✓ Reduced packet loss with larger buffers");
66
67    Ok(())
68}
Source

pub fn with_bandwidth(self, bandwidth: u64) -> Self

Sets the target bandwidth for tests.

Controls the send rate for both TCP and UDP tests. The bandwidth limiter uses a rate-based algorithm that checks bandwidth every 1ms and sleeps when sending too fast.

§Arguments
  • bandwidth - Target bandwidth in bits per second
§Examples
use rperf3::{Config, Protocol};

// UDP test at 100 Mbps
let udp_config = Config::client("127.0.0.1".to_string(), 5201)
    .with_protocol(Protocol::Udp)
    .with_bandwidth(100_000_000); // 100 Mbps

// TCP test at 50 Mbps
let tcp_config = Config::client("127.0.0.1".to_string(), 5201)
    .with_protocol(Protocol::Tcp)
    .with_bandwidth(50_000_000); // 50 Mbps
Examples found in repository?
examples/udp_client.rs (line 13)
5async fn main() -> Result<(), Box<dyn std::error::Error>> {
6    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
7
8    println!("Running UDP test with 50 Mbps target bandwidth...");
9
10    let config = Config::client("127.0.0.1".to_string(), 5201)
11        .with_protocol(Protocol::Udp)
12        .with_duration(Duration::from_secs(10))
13        .with_bandwidth(50 * 1_000_000) // 50 Mbps
14        .with_buffer_size(1024);
15
16    let client = Client::new(config)?;
17    client.run().await?;
18
19    let measurements = client.get_measurements();
20    println!(
21        "\nFinal Results: {:.2} Mbps",
22        measurements.total_bits_per_second() / 1_000_000.0
23    );
24
25    Ok(())
26}
More examples
Hide additional examples
examples/udp_buffer_test.rs (line 40)
20async fn main() -> Result<(), Box<dyn std::error::Error>> {
21    // Initialize logging
22    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
23
24    println!("UDP Socket Optimization Demo");
25    println!("============================\n");
26    println!("This demo tests UDP with:");
27    println!("- 2MB send/receive buffers");
28    println!("- Improved burst handling");
29    println!("- Expected 10-20% improvement with reduced packet loss\n");
30    println!("Note: Make sure the server is running first:");
31    println!("  cargo run --release -- -s -p 5201\n");
32
33    println!("Starting UDP test (5 seconds, 100 Mbps)...\n");
34
35    // Run client test with bandwidth limiting
36    let client_config = Config::client("127.0.0.1".to_string(), 5201)
37        .with_protocol(Protocol::Udp)
38        .with_duration(Duration::from_secs(5))
39        .with_interval(Duration::from_secs(1))
40        .with_bandwidth(100_000_000); // 100 Mbps
41
42    let client = Client::new(client_config)?;
43    client.run().await?;
44
45    // Get measurements
46    let measurements = client.get_measurements();
47    let total_bytes = measurements.total_bytes_sent + measurements.total_bytes_received;
48    let bits_per_second = measurements.total_bits_per_second();
49    let packet_loss = if measurements.total_packets > 0 {
50        (measurements.lost_packets as f64 / measurements.total_packets as f64) * 100.0
51    } else {
52        0.0
53    };
54
55    println!("\n=== Results ===");
56    println!(
57        "Total transferred: {:.2} MB",
58        total_bytes as f64 / 1_000_000.0
59    );
60    println!("Throughput: {:.2} Mbps", bits_per_second / 1_000_000.0);
61    println!("Packet loss: {:.2}%", packet_loss);
62    println!("\nSocket optimizations applied:");
63    println!("✓ Send buffer: 2MB");
64    println!("✓ Recv buffer: 2MB");
65    println!("✓ Reduced packet loss with larger buffers");
66
67    Ok(())
68}
Source

pub fn with_buffer_size(self, size: usize) -> Self

Sets the buffer size for data transfer.

Larger buffer sizes can improve throughput but use more memory.

§Arguments
  • size - Buffer size in bytes (default: 128 KB)
§Examples
use rperf3::Config;

let config = Config::client("127.0.0.1".to_string(), 5201)
    .with_buffer_size(256 * 1024); // 256 KB
Examples found in repository?
examples/client.rs (line 13)
5async fn main() -> Result<(), Box<dyn std::error::Error>> {
6    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
7
8    println!("Connecting to rperf3 server at 127.0.0.1:5201...");
9
10    let config = Config::client("127.0.0.1".to_string(), 5201)
11        .with_protocol(Protocol::Tcp)
12        .with_duration(Duration::from_secs(10))
13        .with_buffer_size(128 * 1024);
14
15    let client = Client::new(config)?;
16    client.run().await?;
17
18    let measurements = client.get_measurements();
19    println!(
20        "\nFinal Results: {:.2} Mbps",
21        measurements.total_bits_per_second() / 1_000_000.0
22    );
23
24    Ok(())
25}
More examples
Hide additional examples
examples/udp_client.rs (line 14)
5async fn main() -> Result<(), Box<dyn std::error::Error>> {
6    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
7
8    println!("Running UDP test with 50 Mbps target bandwidth...");
9
10    let config = Config::client("127.0.0.1".to_string(), 5201)
11        .with_protocol(Protocol::Udp)
12        .with_duration(Duration::from_secs(10))
13        .with_bandwidth(50 * 1_000_000) // 50 Mbps
14        .with_buffer_size(1024);
15
16    let client = Client::new(config)?;
17    client.run().await?;
18
19    let measurements = client.get_measurements();
20    println!(
21        "\nFinal Results: {:.2} Mbps",
22        measurements.total_bits_per_second() / 1_000_000.0
23    );
24
25    Ok(())
26}
examples/client_with_callback.rs (line 59)
49async fn main() -> Result<(), Box<dyn std::error::Error>> {
50    env_logger::init();
51
52    println!("rperf3 Client with Callback Example");
53    println!("====================================\n");
54
55    // Configure the test
56    let config = Config::client("127.0.0.1".to_string(), 5201)
57        .with_protocol(Protocol::Tcp)
58        .with_duration(Duration::from_secs(10))
59        .with_buffer_size(128 * 1024)
60        .with_interval(Duration::from_secs(2)); // Report every 2 seconds
61
62    // Create client with custom callback
63    let client = Client::new(config)?.with_callback(MyProgressCallback);
64
65    println!("Connecting to server at 127.0.0.1:5201...\n");
66
67    // Run the test (callback will be invoked during execution)
68    client.run().await?;
69
70    // Get final measurements
71    let measurements = client.get_measurements();
72    println!("\n📈 Final Statistics:");
73    println!("   Total bytes: {}", measurements.total_bytes_sent);
74    println!(
75        "   Duration: {:.2}s",
76        measurements.total_duration.as_secs_f64()
77    );
78    println!(
79        "   Average bandwidth: {:.2} Mbps",
80        measurements.total_bits_per_second() / 1_000_000.0
81    );
82
83    Ok(())
84}
examples/client_closure_callback.rs (line 20)
6async fn main() -> Result<(), Box<dyn std::error::Error>> {
7    env_logger::init();
8
9    println!("rperf3 Client with Closure Callback Example");
10    println!("===========================================\n");
11
12    // Track progress with shared state
13    let progress = Arc::new(Mutex::new(Vec::new()));
14    let progress_clone = Arc::clone(&progress);
15
16    // Configure the test
17    let config = Config::client("127.0.0.1".to_string(), 5201)
18        .with_protocol(Protocol::Tcp)
19        .with_duration(Duration::from_secs(5))
20        .with_buffer_size(128 * 1024)
21        .with_interval(Duration::from_secs(1));
22
23    // Create client with closure callback
24    let client = Client::new(config)?.with_callback(move |event: ProgressEvent| {
25        match &event {
26            ProgressEvent::TestStarted => {
27                println!("✨ Starting test...");
28            }
29            ProgressEvent::IntervalUpdate {
30                interval_end,
31                bytes,
32                bits_per_second,
33                ..
34            } => {
35                let mbps = bits_per_second / 1_000_000.0;
36                println!(
37                    "⏱️  {:>5.1}s | {:>10} bytes | {:>8.2} Mbps",
38                    interval_end.as_secs_f64(),
39                    bytes,
40                    mbps
41                );
42
43                // Store progress for later analysis
44                if let Ok(mut prog) = progress_clone.lock() {
45                    prog.push((*interval_end, *bytes, *bits_per_second));
46                }
47            }
48            ProgressEvent::TestCompleted {
49                total_bytes,
50                duration,
51                bits_per_second,
52                ..
53            } => {
54                println!("\n🎉 Test finished!");
55                println!("   {} bytes in {:.2}s", total_bytes, duration.as_secs_f64());
56                println!("   Average: {:.2} Mbps", bits_per_second / 1_000_000.0);
57            }
58            ProgressEvent::Error(msg) => {
59                eprintln!("❌ Error: {}", msg);
60            }
61        }
62    });
63
64    println!("Connecting to server at 127.0.0.1:5201...\n");
65
66    // Run the test
67    client.run().await?;
68
69    // Analyze collected progress data
70    if let Ok(prog) = progress.lock() {
71        if !prog.is_empty() {
72            println!("\n📊 Progress Analysis:");
73            let avg_mbps: f64 = prog
74                .iter()
75                .map(|(_, _, bps)| bps / 1_000_000.0)
76                .sum::<f64>()
77                / prog.len() as f64;
78            println!("   Intervals recorded: {}", prog.len());
79            println!("   Average interval speed: {:.2} Mbps", avg_mbps);
80
81            let max_mbps = prog
82                .iter()
83                .map(|(_, _, bps)| bps / 1_000_000.0)
84                .fold(0.0f64, f64::max);
85            let min_mbps = prog
86                .iter()
87                .map(|(_, _, bps)| bps / 1_000_000.0)
88                .fold(f64::INFINITY, f64::min);
89            println!("   Peak speed: {:.2} Mbps", max_mbps);
90            println!("   Lowest speed: {:.2} Mbps", min_mbps);
91        }
92    }
93
94    Ok(())
95}
Source

pub fn with_parallel(self, parallel: usize) -> Self

Sets the number of parallel streams.

Multiple parallel streams can improve throughput by utilizing multiple connections simultaneously. This is particularly useful for high-bandwidth networks where a single stream might not saturate the link.

§Arguments
  • parallel - Number of parallel streams (default: 1)
§Examples
use rperf3::Config;

let config = Config::client("127.0.0.1".to_string(), 5201)
    .with_parallel(4); // Use 4 parallel streams
Source

pub fn with_reverse(self, reverse: bool) -> Self

Enables or disables reverse mode.

In reverse mode, the server sends data and the client receives. In normal mode, the client sends data and the server receives.

§Arguments
  • reverse - true for reverse mode, false for normal mode
§Examples
use rperf3::Config;

let config = Config::client("127.0.0.1".to_string(), 5201)
    .with_reverse(true);
Source

pub fn with_json(self, json: bool) -> Self

Enables or disables JSON output format.

When enabled, results are output in machine-readable JSON format similar to iperf3.

§Arguments
  • json - true to enable JSON output, false for human-readable
§Examples
use rperf3::Config;

let config = Config::client("127.0.0.1".to_string(), 5201)
    .with_json(true);
Examples found in repository?
examples/test_json_output.rs (line 10)
5async fn main() -> Result<(), Box<dyn std::error::Error>> {
6    env_logger::init();
7
8    let config = Config::client("127.0.0.1".to_string(), 5201)
9        .with_duration(Duration::from_secs(3))
10        .with_json(true);
11
12    let client = Client::new(config)?;
13
14    match client.run().await {
15        Ok(_) => println!("\nTest completed successfully"),
16        Err(e) => eprintln!("\nError: {}", e),
17    }
18
19    Ok(())
20}
Source

pub fn with_interval(self, interval: Duration) -> Self

Sets the interval for periodic reporting.

Statistics will be reported at this interval during the test.

§Arguments
  • interval - How often to report statistics (default: 1 second)
§Examples
use rperf3::Config;
use std::time::Duration;

let config = Config::client("127.0.0.1".to_string(), 5201)
    .with_interval(Duration::from_secs(2));
Examples found in repository?
examples/client_with_callback.rs (line 60)
49async fn main() -> Result<(), Box<dyn std::error::Error>> {
50    env_logger::init();
51
52    println!("rperf3 Client with Callback Example");
53    println!("====================================\n");
54
55    // Configure the test
56    let config = Config::client("127.0.0.1".to_string(), 5201)
57        .with_protocol(Protocol::Tcp)
58        .with_duration(Duration::from_secs(10))
59        .with_buffer_size(128 * 1024)
60        .with_interval(Duration::from_secs(2)); // Report every 2 seconds
61
62    // Create client with custom callback
63    let client = Client::new(config)?.with_callback(MyProgressCallback);
64
65    println!("Connecting to server at 127.0.0.1:5201...\n");
66
67    // Run the test (callback will be invoked during execution)
68    client.run().await?;
69
70    // Get final measurements
71    let measurements = client.get_measurements();
72    println!("\n📈 Final Statistics:");
73    println!("   Total bytes: {}", measurements.total_bytes_sent);
74    println!(
75        "   Duration: {:.2}s",
76        measurements.total_duration.as_secs_f64()
77    );
78    println!(
79        "   Average bandwidth: {:.2} Mbps",
80        measurements.total_bits_per_second() / 1_000_000.0
81    );
82
83    Ok(())
84}
More examples
Hide additional examples
examples/tcp_nodelay_test.rs (line 48)
17async fn main() -> Result<(), Box<dyn std::error::Error>> {
18    // Initialize logging
19    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
20
21    println!("TCP Socket Optimization Demo");
22    println!("============================\n");
23    println!("This demo tests TCP with:");
24    println!("- TCP_NODELAY enabled (Nagle's algorithm disabled)");
25    println!("- 256KB send/receive buffers");
26    println!("- Expected 10-20% improvement over default settings\n");
27
28    // Start server in background
29    let server_config = Config::server(5201).with_protocol(Protocol::Tcp);
30    let server = Server::new(server_config);
31
32    // Run server in background task
33    tokio::spawn(async move {
34        if let Err(e) = server.run().await {
35            eprintln!("Server error: {}", e);
36        }
37    });
38
39    // Give server time to start
40    time::sleep(Duration::from_millis(100)).await;
41
42    println!("Starting TCP test (5 seconds)...\n");
43
44    // Run client test
45    let client_config = Config::client("127.0.0.1".to_string(), 5201)
46        .with_protocol(Protocol::Tcp)
47        .with_duration(Duration::from_secs(5))
48        .with_interval(Duration::from_secs(1));
49
50    let client = Client::new(client_config)?;
51    client.run().await?;
52
53    // Get measurements
54    let measurements = client.get_measurements();
55    let total_bytes = measurements.total_bytes_sent + measurements.total_bytes_received;
56    let bits_per_second = measurements.total_bits_per_second();
57
58    println!("\n=== Results ===");
59    println!(
60        "Total transferred: {:.2} MB",
61        total_bytes as f64 / 1_000_000.0
62    );
63    println!("Throughput: {:.2} Mbps", bits_per_second / 1_000_000.0);
64    println!("\nSocket optimizations applied:");
65    println!("✓ TCP_NODELAY: enabled");
66    println!("✓ Send buffer: 256KB");
67    println!("✓ Recv buffer: 256KB");
68
69    Ok(())
70}
examples/udp_buffer_test.rs (line 39)
20async fn main() -> Result<(), Box<dyn std::error::Error>> {
21    // Initialize logging
22    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
23
24    println!("UDP Socket Optimization Demo");
25    println!("============================\n");
26    println!("This demo tests UDP with:");
27    println!("- 2MB send/receive buffers");
28    println!("- Improved burst handling");
29    println!("- Expected 10-20% improvement with reduced packet loss\n");
30    println!("Note: Make sure the server is running first:");
31    println!("  cargo run --release -- -s -p 5201\n");
32
33    println!("Starting UDP test (5 seconds, 100 Mbps)...\n");
34
35    // Run client test with bandwidth limiting
36    let client_config = Config::client("127.0.0.1".to_string(), 5201)
37        .with_protocol(Protocol::Udp)
38        .with_duration(Duration::from_secs(5))
39        .with_interval(Duration::from_secs(1))
40        .with_bandwidth(100_000_000); // 100 Mbps
41
42    let client = Client::new(client_config)?;
43    client.run().await?;
44
45    // Get measurements
46    let measurements = client.get_measurements();
47    let total_bytes = measurements.total_bytes_sent + measurements.total_bytes_received;
48    let bits_per_second = measurements.total_bits_per_second();
49    let packet_loss = if measurements.total_packets > 0 {
50        (measurements.lost_packets as f64 / measurements.total_packets as f64) * 100.0
51    } else {
52        0.0
53    };
54
55    println!("\n=== Results ===");
56    println!(
57        "Total transferred: {:.2} MB",
58        total_bytes as f64 / 1_000_000.0
59    );
60    println!("Throughput: {:.2} Mbps", bits_per_second / 1_000_000.0);
61    println!("Packet loss: {:.2}%", packet_loss);
62    println!("\nSocket optimizations applied:");
63    println!("✓ Send buffer: 2MB");
64    println!("✓ Recv buffer: 2MB");
65    println!("✓ Reduced packet loss with larger buffers");
66
67    Ok(())
68}
examples/client_closure_callback.rs (line 21)
6async fn main() -> Result<(), Box<dyn std::error::Error>> {
7    env_logger::init();
8
9    println!("rperf3 Client with Closure Callback Example");
10    println!("===========================================\n");
11
12    // Track progress with shared state
13    let progress = Arc::new(Mutex::new(Vec::new()));
14    let progress_clone = Arc::clone(&progress);
15
16    // Configure the test
17    let config = Config::client("127.0.0.1".to_string(), 5201)
18        .with_protocol(Protocol::Tcp)
19        .with_duration(Duration::from_secs(5))
20        .with_buffer_size(128 * 1024)
21        .with_interval(Duration::from_secs(1));
22
23    // Create client with closure callback
24    let client = Client::new(config)?.with_callback(move |event: ProgressEvent| {
25        match &event {
26            ProgressEvent::TestStarted => {
27                println!("✨ Starting test...");
28            }
29            ProgressEvent::IntervalUpdate {
30                interval_end,
31                bytes,
32                bits_per_second,
33                ..
34            } => {
35                let mbps = bits_per_second / 1_000_000.0;
36                println!(
37                    "⏱️  {:>5.1}s | {:>10} bytes | {:>8.2} Mbps",
38                    interval_end.as_secs_f64(),
39                    bytes,
40                    mbps
41                );
42
43                // Store progress for later analysis
44                if let Ok(mut prog) = progress_clone.lock() {
45                    prog.push((*interval_end, *bytes, *bits_per_second));
46                }
47            }
48            ProgressEvent::TestCompleted {
49                total_bytes,
50                duration,
51                bits_per_second,
52                ..
53            } => {
54                println!("\n🎉 Test finished!");
55                println!("   {} bytes in {:.2}s", total_bytes, duration.as_secs_f64());
56                println!("   Average: {:.2} Mbps", bits_per_second / 1_000_000.0);
57            }
58            ProgressEvent::Error(msg) => {
59                eprintln!("❌ Error: {}", msg);
60            }
61        }
62    });
63
64    println!("Connecting to server at 127.0.0.1:5201...\n");
65
66    // Run the test
67    client.run().await?;
68
69    // Analyze collected progress data
70    if let Ok(prog) = progress.lock() {
71        if !prog.is_empty() {
72            println!("\n📊 Progress Analysis:");
73            let avg_mbps: f64 = prog
74                .iter()
75                .map(|(_, _, bps)| bps / 1_000_000.0)
76                .sum::<f64>()
77                / prog.len() as f64;
78            println!("   Intervals recorded: {}", prog.len());
79            println!("   Average interval speed: {:.2} Mbps", avg_mbps);
80
81            let max_mbps = prog
82                .iter()
83                .map(|(_, _, bps)| bps / 1_000_000.0)
84                .fold(0.0f64, f64::max);
85            let min_mbps = prog
86                .iter()
87                .map(|(_, _, bps)| bps / 1_000_000.0)
88                .fold(f64::INFINITY, f64::min);
89            println!("   Peak speed: {:.2} Mbps", max_mbps);
90            println!("   Lowest speed: {:.2} Mbps", min_mbps);
91        }
92    }
93
94    Ok(())
95}

Trait Implementations§

Source§

impl Clone for Config

Source§

fn clone(&self) -> Config

Returns a duplicate of the value. Read more
1.0.0§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Config

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Config

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for Config

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for Config

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl Freeze for Config

§

impl RefUnwindSafe for Config

§

impl Send for Config

§

impl Sync for Config

§

impl Unpin for Config

§

impl UnwindSafe for Config

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> CloneToUninit for T
where T: Clone,

§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,