Expand description
§rperf3-rs
A high-performance network throughput measurement tool written in Rust, inspired by iperf3.
This library provides accurate bandwidth testing capabilities for both TCP and UDP protocols. Built on Tokio’s async runtime with Rust’s memory safety guarantees, rperf3-rs eliminates entire classes of bugs (buffer overflows, use-after-free, data races) while achieving 40+ Gbps throughput on localhost tests.
§Features
- TCP & UDP Testing: Measure throughput for both reliable and unreliable protocols
- Bidirectional Testing: Normal mode (client → server) and reverse mode (server → client)
- Bandwidth Limiting: Control send rate for both TCP and UDP with K/M/G notation (e.g., 100M = 100 Mbps)
- UDP Metrics: Packet loss percentage, jitter (RFC 3550), and out-of-order packet detection
- TCP Statistics: Retransmits, congestion window (cwnd), and real-time interval reporting (Linux only)
- Async Interval Reporting: Non-blocking progress updates with 5-10% performance improvement
- Memory-Optimized Storage: Ring buffer design prevents unbounded growth, 30-50% memory reduction
- Lock-Free Measurements: Atomic operations eliminate contention in high-throughput scenarios
- Interval Reporting: Configurable interval updates with iperf3-style formatted output (default: 1 second)
- Real-time Callbacks: Monitor test progress programmatically with event-driven callbacks
- Parallel Streams: Multiple concurrent connections for aggregate testing
- JSON Output: Machine-readable output compatible with automation systems (client and server)
- Dual Interface: Use as a Rust library or standalone CLI tool
- Async I/O: Built on Tokio for high-performance non-blocking operations
- Cross-Platform: Linux, macOS, and Windows support
§Quick Start
§Basic TCP Test
use rperf3::{Client, Config, Protocol};
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = Config::client("192.168.1.100".to_string(), 5201)
.with_protocol(Protocol::Tcp)
.with_duration(Duration::from_secs(10))
.with_interval(Duration::from_secs(1)); // Report every second
let client = Client::new(config)?;
client.run().await?;
let measurements = client.get_measurements();
println!("Bandwidth: {:.2} Mbps",
measurements.total_bits_per_second() / 1_000_000.0);
Ok(())
}§UDP Test with Metrics
use rperf3::{Client, Config, Protocol};
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
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));
let client = Client::new(config)?;
client.run().await?;
let measurements = client.get_measurements();
println!("Bandwidth: {:.2} Mbps",
measurements.total_bits_per_second() / 1_000_000.0);
println!("Packets: {}, Loss: {} ({:.2}%), Jitter: {:.3} ms",
measurements.total_packets,
measurements.lost_packets,
(measurements.lost_packets as f64 / measurements.total_packets as f64) * 100.0,
measurements.jitter_ms);
Ok(())
}§Server Example
use rperf3::{Server, Config};
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Server with JSON output and custom interval
let config = Config::server(5201)
.with_json(true)
.with_interval(Duration::from_secs(2));
let server = Server::new(config);
println!("Server listening on port 5201");
server.run().await?;
Ok(())
}§Progress Callbacks
Monitor test progress in real-time:
use rperf3::{Client, Config, ProgressEvent};
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = Config::client("192.168.1.100".to_string(), 5201)
.with_duration(Duration::from_secs(10));
let client = Client::new(config)?
.with_callback(|event: ProgressEvent| {
match event {
ProgressEvent::TestStarted => {
println!("Test started");
}
ProgressEvent::IntervalUpdate { bits_per_second, .. } => {
println!("Current: {:.2} Mbps", bits_per_second / 1_000_000.0);
}
ProgressEvent::TestCompleted { bits_per_second, .. } => {
println!("Average: {:.2} Mbps", bits_per_second / 1_000_000.0);
}
ProgressEvent::Error(msg) => {
eprintln!("Error: {}", msg);
}
}
});
client.run().await?;
Ok(())
}§Bandwidth Notation
When specifying bandwidth limits, use K/M/G suffixes:
100K= 100,000 bits/second100M= 100,000,000 bits/second1G= 1,000,000,000 bits/second
The bandwidth limiting applies to both TCP (in reverse mode) and UDP tests.
§Interval Reporting
Real-time interval reports show throughput statistics at regular intervals (default: 1 second). Reports use iperf3-compatible formatting with proper alignment:
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 7.23 GBytes 58.1 Gbits/sec 0
[ 5] 1.00-2.00 sec 7.42 GBytes 59.4 Gbits/sec 0 1215 KBytesConfigure intervals with the -i flag or .with_interval() method:
use rperf3::{Client, Config};
use std::time::Duration;
let config = Config::client("192.168.1.100".to_string(), 5201)
.with_duration(Duration::from_secs(10))
.with_interval(Duration::from_secs(2)); // Report every 2 seconds
let client = Client::new(config)?;
client.run().await?;§Architecture
The library is organized into the following modules:
client: Client implementation for initiating tests and collecting resultsserver: Server implementation for handling connections and running testsconfig: Configuration structures with builder patternmeasurements: Thread-safe statistics collection and calculationprotocol: Message format and serialization for client-server communicationudp_packet: UDP packet format with sequence numbers and timestampserror: Custom error types and result aliases
§Performance
Typical performance on modern hardware:
- TCP localhost: 25-30 Gbps
- UDP with limiting: Accurate rate control within 2-3% of target
- Packet loss detection: Sub-millisecond precision
- Jitter measurement: RFC 3550 compliant algorithm
Re-exports§
pub use batch_socket::UdpRecvBatch;pub use batch_socket::UdpSendBatch;pub use batch_socket::MAX_BATCH_SIZE;pub use client::Client;pub use client::ProgressCallback;pub use client::ProgressEvent;pub use config::Config;pub use config::Protocol;pub use error::Error;pub use error::Result;pub use interval_reporter::IntervalMessage;pub use interval_reporter::IntervalReport;pub use interval_reporter::IntervalReporter;pub use measurements::Measurements;pub use protocol::stream_id_for_index;pub use protocol::DEFAULT_STREAM_ID;pub use server::Server;pub use token_bucket::TokenBucket;
Modules§
- batch_
socket - Batch socket operations for improved performance.
- buffer_
pool - Buffer pooling for efficient memory reuse
- client
- config
- error
- interval_
reporter - Interval reporting system for asynchronous performance updates.
- measurements
- protocol
- server
- token_
bucket - Token bucket rate limiter for bandwidth control.
- udp_
packet - UDP packet format with sequence numbers and timestamps for loss/jitter measurement.
Constants§
- VERSION
- Library version string.