pub struct UdpSendBatch { /* private fields */ }Expand description
A batch of UDP packets ready to send.
This structure holds multiple packets that can be sent in a single
sendmmsg system call on Linux, or sent individually on other platforms.
Implementations§
Source§impl UdpSendBatch
impl UdpSendBatch
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new empty batch.
Examples found in repository?
examples/batch_send_test.rs (line 22)
12async fn main() -> Result<(), Box<dyn std::error::Error>> {
13 // Create a UDP socket
14 let socket = UdpSocket::bind("0.0.0.0:0").await?;
15 let local_addr = socket.local_addr()?;
16 println!("Socket bound to: {}", local_addr);
17
18 // Target address (loopback for testing)
19 let target: SocketAddr = "127.0.0.1:5201".parse()?;
20
21 // Create a batch
22 let mut batch = UdpSendBatch::new();
23
24 // Prepare packets
25 let packet_size = 1024;
26 let packet_count = 1000;
27
28 println!(
29 "\nSending {} packets of {} bytes each",
30 packet_count, packet_size
31 );
32 println!("Batch size: {} packets per system call", MAX_BATCH_SIZE);
33
34 // Measure batch sending
35 let start = Instant::now();
36 let mut total_bytes = 0;
37 let mut total_packets = 0;
38 let mut batch_count = 0;
39
40 for i in 0..packet_count {
41 let mut packet = vec![0u8; packet_size];
42 // Add sequence number
43 packet[0..4].copy_from_slice(&(i as u32).to_be_bytes());
44
45 if !batch.add(packet, target) {
46 // Batch is full, send it
47 match batch.send(&socket).await {
48 Ok((bytes, packets)) => {
49 total_bytes += bytes;
50 total_packets += packets;
51 batch_count += 1;
52 }
53 Err(e) => {
54 eprintln!("Error sending batch: {}", e);
55 break;
56 }
57 }
58 }
59 }
60
61 // Send any remaining packets
62 if !batch.is_empty() {
63 match batch.send(&socket).await {
64 Ok((bytes, packets)) => {
65 total_bytes += bytes;
66 total_packets += packets;
67 batch_count += 1;
68 }
69 Err(e) => eprintln!("Error sending final batch: {}", e),
70 }
71 }
72
73 let duration = start.elapsed();
74
75 println!("\n=== Results ===");
76 println!("Total packets sent: {}", total_packets);
77 println!(
78 "Total bytes sent: {} ({:.2} MB)",
79 total_bytes,
80 total_bytes as f64 / 1_000_000.0
81 );
82 println!("Batches sent: {}", batch_count);
83 println!(
84 "Avg packets per batch: {:.1}",
85 total_packets as f64 / batch_count as f64
86 );
87 println!("Duration: {:.3} seconds", duration.as_secs_f64());
88 println!(
89 "Throughput: {:.2} Mbps",
90 (total_bytes * 8) as f64 / duration.as_secs_f64() / 1_000_000.0
91 );
92 println!(
93 "Packet rate: {:.0} pps",
94 total_packets as f64 / duration.as_secs_f64()
95 );
96
97 #[cfg(target_os = "linux")]
98 println!("\n✓ Using Linux sendmmsg for batched operations");
99
100 #[cfg(not(target_os = "linux"))]
101 println!("\n⚠ Using fallback (individual send_to calls)");
102
103 Ok(())
104}Sourcepub fn with_capacity(capacity: usize) -> Self
pub fn with_capacity(capacity: usize) -> Self
Creates a new batch with the specified capacity.
Sourcepub fn add(&mut self, packet: Vec<u8>, addr: SocketAddr) -> bool
pub fn add(&mut self, packet: Vec<u8>, addr: SocketAddr) -> bool
Adds a packet to the batch.
Returns true if the packet was added, false if the batch is full.
Examples found in repository?
examples/batch_send_test.rs (line 45)
12async fn main() -> Result<(), Box<dyn std::error::Error>> {
13 // Create a UDP socket
14 let socket = UdpSocket::bind("0.0.0.0:0").await?;
15 let local_addr = socket.local_addr()?;
16 println!("Socket bound to: {}", local_addr);
17
18 // Target address (loopback for testing)
19 let target: SocketAddr = "127.0.0.1:5201".parse()?;
20
21 // Create a batch
22 let mut batch = UdpSendBatch::new();
23
24 // Prepare packets
25 let packet_size = 1024;
26 let packet_count = 1000;
27
28 println!(
29 "\nSending {} packets of {} bytes each",
30 packet_count, packet_size
31 );
32 println!("Batch size: {} packets per system call", MAX_BATCH_SIZE);
33
34 // Measure batch sending
35 let start = Instant::now();
36 let mut total_bytes = 0;
37 let mut total_packets = 0;
38 let mut batch_count = 0;
39
40 for i in 0..packet_count {
41 let mut packet = vec![0u8; packet_size];
42 // Add sequence number
43 packet[0..4].copy_from_slice(&(i as u32).to_be_bytes());
44
45 if !batch.add(packet, target) {
46 // Batch is full, send it
47 match batch.send(&socket).await {
48 Ok((bytes, packets)) => {
49 total_bytes += bytes;
50 total_packets += packets;
51 batch_count += 1;
52 }
53 Err(e) => {
54 eprintln!("Error sending batch: {}", e);
55 break;
56 }
57 }
58 }
59 }
60
61 // Send any remaining packets
62 if !batch.is_empty() {
63 match batch.send(&socket).await {
64 Ok((bytes, packets)) => {
65 total_bytes += bytes;
66 total_packets += packets;
67 batch_count += 1;
68 }
69 Err(e) => eprintln!("Error sending final batch: {}", e),
70 }
71 }
72
73 let duration = start.elapsed();
74
75 println!("\n=== Results ===");
76 println!("Total packets sent: {}", total_packets);
77 println!(
78 "Total bytes sent: {} ({:.2} MB)",
79 total_bytes,
80 total_bytes as f64 / 1_000_000.0
81 );
82 println!("Batches sent: {}", batch_count);
83 println!(
84 "Avg packets per batch: {:.1}",
85 total_packets as f64 / batch_count as f64
86 );
87 println!("Duration: {:.3} seconds", duration.as_secs_f64());
88 println!(
89 "Throughput: {:.2} Mbps",
90 (total_bytes * 8) as f64 / duration.as_secs_f64() / 1_000_000.0
91 );
92 println!(
93 "Packet rate: {:.0} pps",
94 total_packets as f64 / duration.as_secs_f64()
95 );
96
97 #[cfg(target_os = "linux")]
98 println!("\n✓ Using Linux sendmmsg for batched operations");
99
100 #[cfg(not(target_os = "linux"))]
101 println!("\n⚠ Using fallback (individual send_to calls)");
102
103 Ok(())
104}Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true if the batch is empty.
Examples found in repository?
examples/batch_send_test.rs (line 62)
12async fn main() -> Result<(), Box<dyn std::error::Error>> {
13 // Create a UDP socket
14 let socket = UdpSocket::bind("0.0.0.0:0").await?;
15 let local_addr = socket.local_addr()?;
16 println!("Socket bound to: {}", local_addr);
17
18 // Target address (loopback for testing)
19 let target: SocketAddr = "127.0.0.1:5201".parse()?;
20
21 // Create a batch
22 let mut batch = UdpSendBatch::new();
23
24 // Prepare packets
25 let packet_size = 1024;
26 let packet_count = 1000;
27
28 println!(
29 "\nSending {} packets of {} bytes each",
30 packet_count, packet_size
31 );
32 println!("Batch size: {} packets per system call", MAX_BATCH_SIZE);
33
34 // Measure batch sending
35 let start = Instant::now();
36 let mut total_bytes = 0;
37 let mut total_packets = 0;
38 let mut batch_count = 0;
39
40 for i in 0..packet_count {
41 let mut packet = vec![0u8; packet_size];
42 // Add sequence number
43 packet[0..4].copy_from_slice(&(i as u32).to_be_bytes());
44
45 if !batch.add(packet, target) {
46 // Batch is full, send it
47 match batch.send(&socket).await {
48 Ok((bytes, packets)) => {
49 total_bytes += bytes;
50 total_packets += packets;
51 batch_count += 1;
52 }
53 Err(e) => {
54 eprintln!("Error sending batch: {}", e);
55 break;
56 }
57 }
58 }
59 }
60
61 // Send any remaining packets
62 if !batch.is_empty() {
63 match batch.send(&socket).await {
64 Ok((bytes, packets)) => {
65 total_bytes += bytes;
66 total_packets += packets;
67 batch_count += 1;
68 }
69 Err(e) => eprintln!("Error sending final batch: {}", e),
70 }
71 }
72
73 let duration = start.elapsed();
74
75 println!("\n=== Results ===");
76 println!("Total packets sent: {}", total_packets);
77 println!(
78 "Total bytes sent: {} ({:.2} MB)",
79 total_bytes,
80 total_bytes as f64 / 1_000_000.0
81 );
82 println!("Batches sent: {}", batch_count);
83 println!(
84 "Avg packets per batch: {:.1}",
85 total_packets as f64 / batch_count as f64
86 );
87 println!("Duration: {:.3} seconds", duration.as_secs_f64());
88 println!(
89 "Throughput: {:.2} Mbps",
90 (total_bytes * 8) as f64 / duration.as_secs_f64() / 1_000_000.0
91 );
92 println!(
93 "Packet rate: {:.0} pps",
94 total_packets as f64 / duration.as_secs_f64()
95 );
96
97 #[cfg(target_os = "linux")]
98 println!("\n✓ Using Linux sendmmsg for batched operations");
99
100 #[cfg(not(target_os = "linux"))]
101 println!("\n⚠ Using fallback (individual send_to calls)");
102
103 Ok(())
104}Sourcepub async fn send(&mut self, socket: &UdpSocket) -> Result<(usize, usize)>
pub async fn send(&mut self, socket: &UdpSocket) -> Result<(usize, usize)>
Sends all packets in the batch using the most efficient method available.
On Linux, uses sendmmsg for batched sending. On other platforms,
falls back to individual send_to calls.
Returns the number of bytes sent and the number of packets successfully sent.
Examples found in repository?
examples/batch_send_test.rs (line 47)
12async fn main() -> Result<(), Box<dyn std::error::Error>> {
13 // Create a UDP socket
14 let socket = UdpSocket::bind("0.0.0.0:0").await?;
15 let local_addr = socket.local_addr()?;
16 println!("Socket bound to: {}", local_addr);
17
18 // Target address (loopback for testing)
19 let target: SocketAddr = "127.0.0.1:5201".parse()?;
20
21 // Create a batch
22 let mut batch = UdpSendBatch::new();
23
24 // Prepare packets
25 let packet_size = 1024;
26 let packet_count = 1000;
27
28 println!(
29 "\nSending {} packets of {} bytes each",
30 packet_count, packet_size
31 );
32 println!("Batch size: {} packets per system call", MAX_BATCH_SIZE);
33
34 // Measure batch sending
35 let start = Instant::now();
36 let mut total_bytes = 0;
37 let mut total_packets = 0;
38 let mut batch_count = 0;
39
40 for i in 0..packet_count {
41 let mut packet = vec![0u8; packet_size];
42 // Add sequence number
43 packet[0..4].copy_from_slice(&(i as u32).to_be_bytes());
44
45 if !batch.add(packet, target) {
46 // Batch is full, send it
47 match batch.send(&socket).await {
48 Ok((bytes, packets)) => {
49 total_bytes += bytes;
50 total_packets += packets;
51 batch_count += 1;
52 }
53 Err(e) => {
54 eprintln!("Error sending batch: {}", e);
55 break;
56 }
57 }
58 }
59 }
60
61 // Send any remaining packets
62 if !batch.is_empty() {
63 match batch.send(&socket).await {
64 Ok((bytes, packets)) => {
65 total_bytes += bytes;
66 total_packets += packets;
67 batch_count += 1;
68 }
69 Err(e) => eprintln!("Error sending final batch: {}", e),
70 }
71 }
72
73 let duration = start.elapsed();
74
75 println!("\n=== Results ===");
76 println!("Total packets sent: {}", total_packets);
77 println!(
78 "Total bytes sent: {} ({:.2} MB)",
79 total_bytes,
80 total_bytes as f64 / 1_000_000.0
81 );
82 println!("Batches sent: {}", batch_count);
83 println!(
84 "Avg packets per batch: {:.1}",
85 total_packets as f64 / batch_count as f64
86 );
87 println!("Duration: {:.3} seconds", duration.as_secs_f64());
88 println!(
89 "Throughput: {:.2} Mbps",
90 (total_bytes * 8) as f64 / duration.as_secs_f64() / 1_000_000.0
91 );
92 println!(
93 "Packet rate: {:.0} pps",
94 total_packets as f64 / duration.as_secs_f64()
95 );
96
97 #[cfg(target_os = "linux")]
98 println!("\n✓ Using Linux sendmmsg for batched operations");
99
100 #[cfg(not(target_os = "linux"))]
101 println!("\n⚠ Using fallback (individual send_to calls)");
102
103 Ok(())
104}Trait Implementations§
Source§impl Debug for UdpSendBatch
impl Debug for UdpSendBatch
Auto Trait Implementations§
impl Freeze for UdpSendBatch
impl RefUnwindSafe for UdpSendBatch
impl Send for UdpSendBatch
impl Sync for UdpSendBatch
impl Unpin for UdpSendBatch
impl UnwindSafe for UdpSendBatch
Blanket Implementations§
§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more