Skip to main content

rust_raknet/
lib.rs

1//! An asynchronous implementation of the RakNet transport protocol in Rust.
2//!
3//! RakNet provides reliable and ordered delivery modes over UDP and is used by
4//! Minecraft Bedrock Edition. This library implements the connection handshake,
5//! packet reliability, fragmentation, and listener/client APIs.
6//!
7//! The library requires the Tokio 1.x asynchronous runtime.
8//!
9//! # Features
10//!
11//! - Asynchronous client and server APIs
12//! - Five RakNet reliability modes
13//! - Selective retransmission and fast acknowledgements
14//! - IPv4 and IPv6 socket addresses
15//!
16//! # Getting started
17//!
18//! ```toml
19//! [dependencies]
20//! rust-raknet = "1.2.0"
21//! ```
22//!
23//! # Reliability modes
24//!
25//! - Unreliable
26//! - Unreliable sequenced
27//! - Reliable
28//! - Reliable ordered
29//! - Reliable sequenced
30//!
31//! This project is not affiliated with Jenkins Software LLC or RakNet.
32//! See the [RakNet protocol reference](http://www.jenkinssoftware.com/raknet/manual/index.html).
33
34mod arq;
35mod datatype;
36pub mod error;
37mod fragment;
38mod log;
39mod packet;
40#[cfg(feature = "recovery-policy")]
41mod recovery_options;
42#[cfg(feature = "send-policy")]
43mod send_options;
44mod sequence;
45mod server;
46mod socket;
47mod udp;
48mod utils;
49
50pub use crate::arq::Reliability;
51pub use crate::log::enable_raknet_log;
52#[cfg(feature = "recovery-policy")]
53pub use crate::recovery_options::RecoveryOptions;
54#[cfg(feature = "send-policy")]
55pub use crate::send_options::{SendOptions, SendOptionsError};
56pub use crate::server::*;
57pub use crate::socket::*;
58pub use bytes::Bytes;
59
60#[test]
61fn test_raknet_error_implements_std_error() {
62    fn assert_error<T: std::error::Error>() {}
63    assert_error::<error::RaknetError>();
64    assert_eq!(
65        error::RaknetError::NotListen.to_string(),
66        "the RakNet listener is not listening"
67    );
68}
69
70#[tokio::test]
71async fn test_listener_updates_motd_after_listen() {
72    let mut listener = RaknetListener::bind(&"127.0.0.1:0".parse().unwrap())
73        .await
74        .unwrap();
75    let local_addr = listener.local_addr().unwrap();
76    listener.listen().await;
77
78    let motd = "MCPE;Updated MOTD;486;1.20.0;0;20;123;World;Survival;1;19132;";
79    listener.set_full_motd(motd.to_owned()).await.unwrap();
80
81    let (_, received_motd) = tokio::time::timeout(
82        std::time::Duration::from_secs(3),
83        RaknetSocket::ping(&local_addr),
84    )
85    .await
86    .expect("server did not answer the unconnected ping")
87    .unwrap();
88    assert_eq!(received_motd, motd);
89
90    listener.close().await.unwrap();
91}
92
93#[tokio::test]
94async fn test_listener_accepts_more_than_one_queue_of_connections() {
95    const CONNECTIONS: usize = 12;
96
97    let mut listener = RaknetListener::bind(&"127.0.0.1:0".parse().unwrap())
98        .await
99        .unwrap();
100    let local_addr = listener.local_addr().unwrap();
101    listener.listen().await;
102
103    let accept_task = tokio::spawn(async move {
104        let mut accepted = Vec::with_capacity(CONNECTIONS);
105        for _ in 0..CONNECTIONS {
106            accepted.push(
107                tokio::time::timeout(std::time::Duration::from_secs(5), listener.accept())
108                    .await
109                    .expect("listener stopped accepting connections")
110                    .unwrap(),
111            );
112        }
113        (accepted, listener)
114    });
115
116    let mut clients = Vec::with_capacity(CONNECTIONS);
117    for _ in 0..CONNECTIONS {
118        clients.push(
119            tokio::time::timeout(
120                std::time::Duration::from_secs(5),
121                RaknetSocket::connect(&local_addr),
122            )
123            .await
124            .expect("client connection timed out")
125            .unwrap(),
126        );
127    }
128
129    let (accepted, mut listener) =
130        tokio::time::timeout(std::time::Duration::from_secs(5), accept_task)
131            .await
132            .expect("listener accept loop timed out")
133            .unwrap();
134    assert_eq!(accepted.len(), CONNECTIONS);
135
136    for socket in clients {
137        socket.close().await.unwrap();
138    }
139    for socket in accepted {
140        socket.close().await.unwrap();
141    }
142    listener.close().await.unwrap();
143}
144
145#[tokio::test]
146async fn test_connect() {
147    let mut server = RaknetListener::bind(&"127.0.0.1:0".parse().unwrap())
148        .await
149        .unwrap();
150    let local_addr = server.local_addr().unwrap();
151    server.listen().await;
152
153    let notify = std::sync::Arc::new(tokio::sync::Notify::new());
154    let notify2 = notify.clone();
155
156    tokio::spawn(async move {
157        let client1 = server.accept().await.unwrap();
158        assert!(client1.local_addr().unwrap() == local_addr);
159        client1
160            .send(&[0xfe, 2, 3], Reliability::Reliable)
161            .await
162            .unwrap();
163        notify2.notified().await;
164    });
165    let client2 = RaknetSocket::connect(&local_addr).await.unwrap();
166    assert!(client2.peer_addr().unwrap() == local_addr);
167    let buf = client2.recv().await.unwrap();
168    assert!(buf == vec![0xfe, 2, 3]);
169
170    notify.notify_one();
171}
172
173#[tokio::test]
174async fn test_send_recv_fragment_data() {
175    let mut server = RaknetListener::bind(&"127.0.0.1:0".parse().unwrap())
176        .await
177        .unwrap();
178    let local_addr = server.local_addr().unwrap();
179    server.listen().await;
180
181    let notify = std::sync::Arc::new(tokio::sync::Notify::new());
182    let notify2 = notify.clone();
183
184    tokio::spawn(async move {
185        let client1 = server.accept().await.unwrap();
186        assert!(client1.local_addr().unwrap() == local_addr);
187
188        let mut a = vec![3u8; 1000];
189        let mut b = vec![2u8; 1000];
190        let mut c = vec![0xfe; 1000];
191        b.append(&mut a);
192        c.append(&mut b);
193
194        client1
195            .send(&c, Reliability::ReliableOrdered)
196            .await
197            .unwrap();
198
199        notify2.notified().await;
200    });
201    let client2 = RaknetSocket::connect(&local_addr).await.unwrap();
202    assert!(client2.peer_addr().unwrap() == local_addr);
203    let buf = client2.recv().await.unwrap();
204    assert!(buf.len() == 3000);
205    assert!(buf[0..1000] == vec![0xfe; 1000]);
206    assert!(buf[1000..2000] == vec![2u8; 1000]);
207    assert!(buf[2000..3000] == vec![3u8; 1000]);
208
209    notify.notify_one();
210}
211
212#[tokio::test]
213async fn test_send_recv_more_reliability_type_packet() {
214    let mut server = RaknetListener::bind(&"127.0.0.1:0".parse().unwrap())
215        .await
216        .unwrap();
217    let local_addr = server.local_addr().unwrap();
218    server.listen().await;
219
220    let notify = std::sync::Arc::new(tokio::sync::Notify::new());
221    let notify2 = notify.clone();
222
223    tokio::spawn(async move {
224        let client1 = server.accept().await.unwrap();
225        assert!(client1.local_addr().unwrap() == local_addr);
226
227        client1
228            .send(&[0xfe, 1, 2, 3], Reliability::Unreliable)
229            .await
230            .unwrap();
231        let data = client1.recv().await.unwrap();
232        assert!(data == [0xfe, 4, 5, 6].to_vec());
233
234        client1
235            .send(&[0xfe, 7, 8, 9], Reliability::UnreliableSequenced)
236            .await
237            .unwrap();
238        let data = client1.recv().await.unwrap();
239        assert!(data == [0xfe, 10, 11, 12].to_vec());
240
241        client1
242            .send(&[0xfe, 13, 14, 15], Reliability::Reliable)
243            .await
244            .unwrap();
245        let data = client1.recv().await.unwrap();
246        assert!(data == [0xfe, 16, 17, 18].to_vec());
247
248        let mut a = vec![3u8; 1000];
249        let mut b = vec![2u8; 1000];
250        let mut c = vec![0xfe; 1000];
251        b.append(&mut a);
252        c.append(&mut b);
253
254        client1
255            .send(&c, Reliability::ReliableOrdered)
256            .await
257            .unwrap();
258
259        let buf = client1.recv().await.unwrap();
260        assert!(buf.len() == 3000);
261        assert!(buf[0..1000] == vec![0xfe; 1000]);
262        assert!(buf[1000..2000] == vec![2u8; 1000]);
263        assert!(buf[2000..3000] == vec![3u8; 1000]);
264
265        client1
266            .send(&[0xfe, 19, 20, 21], Reliability::ReliableSequenced)
267            .await
268            .unwrap();
269        let data = client1.recv().await.unwrap();
270        assert!(data == [0xfe, 22, 23, 24].to_vec());
271
272        notify2.notified().await;
273    });
274    let client2 = RaknetSocket::connect(&local_addr).await.unwrap();
275    assert!(client2.peer_addr().unwrap() == local_addr);
276
277    let buf = client2.recv().await.unwrap();
278    assert!(buf == [0xfe, 1, 2, 3]);
279
280    client2
281        .send(&[0xfe, 4, 5, 6], Reliability::Unreliable)
282        .await
283        .unwrap();
284
285    let buf = client2.recv().await.unwrap();
286    assert!(buf == [0xfe, 7, 8, 9]);
287
288    client2
289        .send(&[0xfe, 10, 11, 12], Reliability::UnreliableSequenced)
290        .await
291        .unwrap();
292
293    let buf = client2.recv().await.unwrap();
294    assert!(buf == [0xfe, 13, 14, 15]);
295
296    client2
297        .send(&[0xfe, 16, 17, 18], Reliability::Reliable)
298        .await
299        .unwrap();
300
301    let buf = client2.recv().await.unwrap();
302    assert!(buf.len() == 3000);
303    assert!(buf[0..1000] == vec![0xfe; 1000]);
304    assert!(buf[1000..2000] == vec![2u8; 1000]);
305    assert!(buf[2000..3000] == vec![3u8; 1000]);
306
307    let mut a = vec![3u8; 1000];
308    let mut b = vec![2u8; 1000];
309    let mut c = vec![0xfe; 1000];
310    b.append(&mut a);
311    c.append(&mut b);
312
313    client2
314        .send(&c, Reliability::ReliableOrdered)
315        .await
316        .unwrap();
317
318    let buf = client2.recv().await.unwrap();
319    assert!(buf == [0xfe, 19, 20, 21]);
320
321    client2
322        .send(&[0xfe, 22, 23, 24], Reliability::ReliableSequenced)
323        .await
324        .unwrap();
325
326    notify.notify_one();
327}
328
329#[tokio::test]
330async fn test_loss_packet1() {
331    let notify = std::sync::Arc::new(tokio::sync::Notify::new());
332    let notify2 = notify.clone();
333    let mut server = RaknetListener::bind(&"127.0.0.1:0".parse().unwrap())
334        .await
335        .unwrap();
336    let local_addr = server.local_addr().unwrap();
337    server.listen().await;
338    tokio::spawn(async move {
339        let mut client1 = server.accept().await.unwrap();
340        // Simulate 20% packet loss.
341        client1.set_loss_rate(2);
342
343        for i in 0..10 {
344            let mut flag = vec![0xfe_u8];
345            let mut data = vec![i as u8; 2000];
346            flag.append(&mut data);
347            client1
348                .send(&flag, Reliability::ReliableOrdered)
349                .await
350                .unwrap();
351
352            let data = client1.recv().await.unwrap();
353            assert!(data == flag);
354        }
355
356        notify2.notified().await;
357    });
358    let mut client2 = RaknetSocket::connect(&local_addr).await.unwrap();
359    // Simulate 20% packet loss.
360    client2.set_loss_rate(2);
361
362    for i in 0..10 {
363        let mut flag = vec![0xfe_u8];
364        let mut data = vec![i as u8; 2000];
365        flag.append(&mut data);
366        client2
367            .send(&flag, Reliability::ReliableOrdered)
368            .await
369            .unwrap();
370
371        let data = client2.recv().await.unwrap();
372        assert!(data == flag);
373    }
374    notify.notify_one();
375}
376
377#[tokio::test]
378async fn test_loss_packet2() {
379    let notify = std::sync::Arc::new(tokio::sync::Notify::new());
380    let notify2 = notify.clone();
381    let mut server = RaknetListener::bind(&"127.0.0.1:0".parse().unwrap())
382        .await
383        .unwrap();
384    let local_addr = server.local_addr().unwrap();
385    server.listen().await;
386    tokio::spawn(async move {
387        let mut client1 = server.accept().await.unwrap();
388        // Simulate 20% packet loss.
389        client1.set_loss_rate(2);
390
391        for i in 0..10 {
392            let mut flag = vec![0xfe_u8];
393            let mut data = vec![i as u8; 2000];
394            flag.append(&mut data);
395            client1
396                .send(&flag, Reliability::ReliableOrdered)
397                .await
398                .unwrap();
399        }
400
401        for i in 0..10 {
402            let mut flag = vec![0xfe_u8];
403            let mut data = vec![i as u8; 2000];
404            flag.append(&mut data);
405            let data = client1.recv().await.unwrap();
406            assert!(data == flag);
407        }
408        notify2.notified().await;
409    });
410    let mut client2 = RaknetSocket::connect(&local_addr).await.unwrap();
411    // Simulate 20% packet loss.
412    client2.set_loss_rate(2);
413
414    for i in 0..10 {
415        let mut flag = vec![0xfe_u8];
416        let mut data = vec![i as u8; 2000];
417        flag.append(&mut data);
418        client2
419            .send(&flag, Reliability::ReliableOrdered)
420            .await
421            .unwrap();
422    }
423
424    for i in 0..10 {
425        let mut flag = vec![0xfe_u8];
426        let mut data = vec![i as u8; 2000];
427        flag.append(&mut data);
428        let data = client2.recv().await.unwrap();
429        assert!(data == flag);
430    }
431    notify.notify_one();
432}
433
434#[tokio::test]
435async fn test_loss_packet_with_sequenced() {
436    let notify = std::sync::Arc::new(tokio::sync::Notify::new());
437    let notify2 = notify.clone();
438    let mut server = RaknetListener::bind(&"127.0.0.1:0".parse().unwrap())
439        .await
440        .unwrap();
441    let local_addr = server.local_addr().unwrap();
442    server.listen().await;
443    tokio::spawn(async move {
444        let mut client1 = server.accept().await.unwrap();
445        // Simulate 20% packet loss.
446        client1.set_loss_rate(2);
447
448        for i in 0..100 {
449            let mut flag = vec![0xfe_u8];
450            let mut data = vec![i as u8; 20];
451            flag.append(&mut data);
452            client1
453                .send(&flag, Reliability::ReliableSequenced)
454                .await
455                .unwrap();
456        }
457
458        let mut last = 0;
459        for i in 0..50 {
460            let mut flag = vec![0xfe_u8];
461            let mut data = vec![i as u8; 20];
462            flag.append(&mut data);
463            let data = client1.recv().await.unwrap();
464            assert!(data[1] >= last);
465            last = data[1];
466        }
467        notify2.notified().await;
468    });
469    let mut client2 = RaknetSocket::connect(&local_addr).await.unwrap();
470    // Simulate 20% packet loss.
471    client2.set_loss_rate(2);
472
473    for i in 0..100 {
474        let mut flag = vec![0xfe_u8];
475        let mut data = vec![i as u8; 20];
476        flag.append(&mut data);
477        client2
478            .send(&flag, Reliability::ReliableSequenced)
479            .await
480            .unwrap();
481    }
482
483    let mut last = 0;
484    for i in 0..50 {
485        let mut flag = vec![0xfe_u8];
486        let mut data = vec![i as u8; 20];
487        flag.append(&mut data);
488        let data = client2.recv().await.unwrap();
489        assert!(data[1] >= last);
490        last = data[1];
491    }
492    notify.notify_one();
493}
494
495#[tokio::test]
496async fn test_raknet_server_close() {
497    for _ in 0..10 {
498        let mut server = RaknetListener::bind(&"127.0.0.1:19132".parse().unwrap())
499            .await
500            .unwrap();
501        server.listen().await;
502        let client = RaknetSocket::connect(&"127.0.0.1:19132".parse().unwrap())
503            .await
504            .unwrap();
505        let mut a = vec![3u8; 1000];
506        let mut b = vec![2u8; 1000];
507        let mut c = vec![0xfe; 1000];
508        b.append(&mut a);
509        c.append(&mut b);
510        client.send(&c, Reliability::ReliableOrdered).await.unwrap();
511
512        let client2 = server.accept().await.unwrap();
513        let buf = client2.recv().await.unwrap();
514        assert!(buf.len() == 3000);
515        assert!(buf[0..1000] == vec![0xfe; 1000]);
516        assert!(buf[1000..2000] == vec![2u8; 1000]);
517        assert!(buf[2000..3000] == vec![3u8; 1000]);
518
519        server.close().await.unwrap();
520        client.close().await.unwrap();
521    }
522
523    let mut server1 = RaknetListener::bind(&"127.0.0.1:19132".parse().unwrap())
524        .await
525        .unwrap();
526    server1.listen().await;
527    server1.close().await.unwrap();
528    let mut server2 = RaknetListener::bind(&"127.0.0.1:19132".parse().unwrap())
529        .await
530        .unwrap();
531    server2.listen().await;
532}
533
534#[tokio::test]
535async fn test_send_recv_full_packet() {
536    let mut server = RaknetListener::bind(&"127.0.0.1:0".parse().unwrap())
537        .await
538        .unwrap();
539    let remote_addr = format!("127.0.0.1:{}", server.local_addr().unwrap().port());
540    tokio::spawn(async move {
541        server.listen().await;
542        let client = server.accept().await.unwrap();
543
544        // Complete delivery requires ordered reliability; sequenced mode may
545        // discard superseded messages during retransmission.
546        for _ in 0..50 {
547            client
548                .send(&vec![0xfe; 1000], Reliability::ReliableOrdered)
549                .await
550                .unwrap();
551        }
552        client.flush().await.unwrap();
553
554        client.close().await.unwrap();
555        server.close().await.unwrap();
556    });
557
558    let client = RaknetSocket::connect(&remote_addr.parse().unwrap())
559        .await
560        .unwrap();
561
562    for _ in 0..50 {
563        let buf = client.recv().await.unwrap();
564        assert!(buf == [0xfe; 1000]);
565    }
566}
567
568#[tokio::test]
569async fn test_send_recv_with_flush() {
570    let mut server = RaknetListener::bind(&"127.0.0.1:0".parse().unwrap())
571        .await
572        .unwrap();
573    let remote_addr = format!("127.0.0.1:{}", server.local_addr().unwrap().port());
574    let s1 = std::sync::Arc::new(tokio::sync::Semaphore::new(1));
575    let s2 = s1.clone();
576    tokio::spawn(async move {
577        server.listen().await;
578        let client = server.accept().await.unwrap();
579
580        for _ in 0..50 {
581            #[allow(unused_must_use)]
582            {
583                s1.acquire().await.unwrap();
584            }
585            client
586                .send(&vec![0xfe; 1000], Reliability::ReliableSequenced)
587                .await
588                .unwrap();
589            client.flush().await.unwrap();
590        }
591
592        client.close().await.unwrap();
593        for _ in 0..5 {
594            client
595                .send(&vec![0xfe; 1000], Reliability::ReliableSequenced)
596                .await
597                .unwrap();
598            match match client.flush().await {
599                Ok(_) => panic!("incorrect return"),
600                Err(e) => e,
601            } {
602                error::RaknetError::ConnectionClosed => {}
603                _ => panic!("incorrect return"),
604            };
605        }
606        server.close().await.unwrap();
607    });
608
609    let client = RaknetSocket::connect(&remote_addr.parse().unwrap())
610        .await
611        .unwrap();
612
613    for _ in 0..50 {
614        let buf = client.recv().await.unwrap();
615        assert!(buf == [0xfe; 1000]);
616        s2.add_permits(1);
617    }
618}
619
620/*
621#[tokio::test]
622async fn chore2(){
623
624    enbale_raknet_log(true);
625    let mut listener = RaknetListener::bind("0.0.0.0:19199".parse().unwrap()).await.unwrap();
626    listener.listen().await;
627    loop{
628        let mut client1 = listener.accept().await.unwrap();
629        let mut client2 = RaknetSocket::connect(&"192.168.199.127:19132".parse().unwrap()).await.unwrap();
630        tokio::spawn(async move {
631            println!("build connection");
632            loop{
633                tokio::select!{
634                    a = client1.recv() => {
635                        let a = match a{
636                            Ok(p) => p,
637                            Err(_) => {
638                                client2.close().await.unwrap();
639                                break;
640                            },
641                        };
642                        match client2.send(&a, Reliability::ReliableOrdered).await{
643                            Ok(p) => p,
644                            Err(_) => {
645                                client1.close().await.unwrap();
646                                break;
647                            },
648                        };
649                    },
650                    b = client2.recv() => {
651                        let b = match b{
652                            Ok(p) => p,
653                            Err(_) => {
654                                client1.close().await.unwrap();
655                                break;
656                            },
657                        };
658                        match client1.send(&b, Reliability::ReliableOrdered).await{
659                            Ok(p) => p,
660                            Err(_) => {
661                                client2.close().await.unwrap();
662                                break;
663                            },
664                        };
665                    }
666                }
667            }
668            println!("close connection");
669        });
670    }
671
672
673}
674*/
675
676#[cfg(feature = "send-policy")]
677#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
678async fn mixed_send_options_preserve_reliable_order_and_deliver_unreliable_data() {
679    use std::sync::Arc;
680    let mut listener = RaknetListener::bind(&"127.0.0.1:0".parse().unwrap())
681        .await
682        .unwrap();
683    listener.listen().await;
684    let address = listener.local_addr().unwrap();
685    let options = SendOptions::default()
686        .with_in_flight_limits(128, 8192)
687        .unwrap()
688        .with_queue_budgets(4096, 2048)
689        .unwrap()
690        .with_flush_budget(2048)
691        .unwrap();
692    let client = Arc::new(RaknetSocket::connect(&address).await.unwrap());
693    assert_eq!(client.send_options().await, None);
694    client.set_send_options(options).await.unwrap();
695    assert_eq!(client.send_options().await, Some(options));
696    let server = listener.accept().await.unwrap();
697    let reliable = client.clone();
698    let send_reliable = tokio::spawn(async move {
699        for index in 0..100u8 {
700            let mut data = [0xfe; 128];
701            data[1] = 0;
702            data[2] = index;
703            reliable
704                .send(&data, Reliability::ReliableOrdered)
705                .await
706                .unwrap();
707        }
708        reliable.flush().await.unwrap();
709    });
710    let unreliable = client.clone();
711    let send_unreliable = tokio::spawn(async move {
712        for index in 0..100u8 {
713            let mut data = [0xfe; 64];
714            data[1] = 1;
715            data[2] = index;
716            unreliable
717                .send(&data, Reliability::Unreliable)
718                .await
719                .unwrap();
720            tokio::task::yield_now().await;
721        }
722    });
723    tokio::time::timeout(std::time::Duration::from_secs(5), async {
724        let mut ordered = 0u8;
725        let mut unordered = 0usize;
726        for _ in 0..200 {
727            let data = server.recv().await.unwrap();
728            if data[1] == 0 {
729                assert_eq!(data[2], ordered);
730                ordered += 1;
731            } else {
732                unordered += 1;
733            }
734        }
735        assert_eq!(ordered, 100);
736        assert_eq!(unordered, 100);
737        send_reliable.await.unwrap();
738        send_unreliable.await.unwrap();
739    })
740    .await
741    .unwrap();
742    client.close().await.unwrap();
743    server.close().await.unwrap();
744    listener.close().await.unwrap();
745}
746
747#[cfg(feature = "send-policy")]
748#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
749async fn unreliable_batch_streams_beyond_the_queue_reserve() {
750    let mut listener = RaknetListener::bind(&"127.0.0.1:0".parse().unwrap())
751        .await
752        .unwrap();
753    listener.listen().await;
754    let client = RaknetSocket::connect(&listener.local_addr().unwrap())
755        .await
756        .unwrap();
757    client
758        .set_send_options(
759            SendOptions::default()
760                .with_queue_budgets(4096, 2048)
761                .unwrap(),
762        )
763        .await
764        .unwrap();
765    let server = listener.accept().await.unwrap();
766    let messages = (0..100u8)
767        .map(|i| {
768            let mut d = vec![0xfe; 64];
769            d[1] = i;
770            d
771        })
772        .collect::<Vec<_>>();
773    let borrowed = messages.iter().map(Vec::as_slice).collect::<Vec<_>>();
774    tokio::time::timeout(std::time::Duration::from_secs(5), async {
775        client
776            .send_batch(&borrowed, Reliability::Unreliable)
777            .await
778            .unwrap();
779        let mut received = std::collections::HashSet::new();
780        for _ in 0..100 {
781            let data = server.recv().await.unwrap();
782            assert_eq!(data.len(), 64);
783            assert!(received.insert(data[1]));
784        }
785    })
786    .await
787    .unwrap();
788    client.close().await.unwrap();
789    server.close().await.unwrap();
790    listener.close().await.unwrap();
791}