1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
//! [![github]](https://github.com/mahmoudkhera/udpopt) [![crates-io]](https://crates.io/crates/udpopt) [![docs-rs]](https://docs.rs/udpopt)
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
//!
//! <br>
//!
//! A high-performance synchronous and asynchronous UDP testing toolkit for sending and receiving UDP packets
//! with precise timing and bitrate control.
//!
//!
//! # Details
//!
//!
//! - Use `udpopt::UdpClient` to represent the test client
//! ```
//! use std::net::UdpSocket;
//! use std::sync::mpsc;
//! use std::thread;
//! use std::time::Duration;
//! use udpopt::UdpClient;
//! use udpopt::ClientCommand;
//!
//! fn main() {
//!
//! # let mut sock = UdpSocket::bind("127.0.0.1:4000").expect("failed to bind");
//!
//! // Connect to server address
//! # sock.connect("127.0.0.1:5000").expect("failed to connect");
//!
//!
//! let (tx, rx) = mpsc::channel();
//!
//! // Create a UDP client instance
//! let mut client = UdpClient::new(
//! 1_000_000.0, // bitrate in bits per second
//! 1200, // payload size in bytes
//! Duration::from_secs(5), // send duration
//! rx, // control receiver
//! );
//!
//! // Spawn the client in a separate thread
//! let handle = thread::spawn(move || {
//! client.run(&mut sock).unwrap();
//! });
//!
//! // Send start command
//! tx.send(ClientCommand::Start).unwrap();
//!
//! // Wait for client to finish
//! handle.join().unwrap();
//! }
//!
//! ```
//! #
//!
//! - After the duration is done the after 5 seconds the otput should be
//!
//! ```console
//! Client done. Sent 'Number of packets' packets (+FIN)
//!
//! ```
//!
//! - Use `udpopt::UdpServer` to represent the test server
//!
//! ```
//! use std::net::UdpSocket;
//! use std::sync::mpsc;
//! use std::thread;
//! use std::time::Duration;
//! use udpopt::UdpServer;
//! use udpopt::ServerCommand;
//!
//! fn main() {
//! # // Bind UDP socket to listen on port 5000
//! # let mut sock = UdpSocket::bind("127.0.0.1:5000").expect("failed to bind");
//!
//!
//! // Create a channel for controlling the server (start/stop)
//! let (tx, rx) = mpsc::channel();
//!
//! // Create a server that saves results every 5 seconds
//! let mut server = UdpServer::new(Duration::from_secs(5), rx);
//!
//! // Run the server in a separate thread
//! let handle = thread::spawn(move || server.run(&mut sock));
//!
//! // Start the test
//! tx.send(ServerCommand::Start).unwrap();
//!
//! // Simulate running for a while
//! thread::sleep(Duration::from_secs(1));
//!
//! // Stop the server
//! tx.send(ServerCommand::Stop).unwrap();
//!
//! // Wait for the server thread to finish
//! let result = handle.join().unwrap();
//!
//! # println!("Server finished: {:?}", result);
//!
//! }
//! ```
//!
//! - This module defines the [`TestResult`] struct, which aggregates multiple
//! [`IntervalResult`] measurements that results from `UdpServer::run`
//! into final performance metrics — total packets, bitrate, jitter, and more.
//! Simulated interval results (normally collected by a UDP server)
//!
//!
//! ```rust
//! use std::time::Duration;
//! use udpopt::IntervalResult;
//! use udpopt::TestResult;
//!
//! # let intervals = vec![
//! # IntervalResult {
//! # received: 950,
//! # lost: 50,
//! # bytes: 1_200_000,
//! # time: Duration::from_secs(1),
//! # jitter_ms: 0.8,
//! # out_of_order: 2,
//! # recommended_bitrate: 0,
//! # },
//! # IntervalResult {
//! # received: 970,
//! # lost: 30,
//! # bytes: 1_250_000,
//! # time: Duration::from_secs(1),
//! # jitter_ms: 1.2,
//! # out_of_order: 1,
//! # recommended_bitrate: 0,
//! # },
//! # ];
//!
//! // Aggregate the results
//! let result = TestResult::from_intervals(&intervals);
//! println!("Total lost: {}", result.total_lost);
//! println!("Total bytes: {}", result.total_bytes);
//! println!("Total out of order: {}", result.total_out_of_order);
//! println!("Total packets: {}", result.total_packets);
//! println!("Mean bitrate: {:.2} bps", result.mean_bitrate);
//! println!("Median jitter: {:.2} ms", result.median_jitter);
//! ```
//!
//!
//! - This produces an output similar to:
//! ```text
//! Total lost: 80
//! Total bytes: 2450000
//! Total out of order: 1
//! Total packets: 1920
//! Mean bitrate: 9.60e6 bps
//! Median jitter: 1.00 ms
//! ```
pub use UdpClient;
pub use UdpOptError;
pub use TestResult;
pub use UdpServer;
pub use ;
pub use ui;
// async part
pub use AsyncUdpClient;
pub use AsyncUdpServer;