1//! Simple TCP echo server to check memory leaks using Valgrind.
2use std::{thread::sleep, time::Duration};
3
4use tokio::{
5 io::{AsyncReadExt, AsyncWriteExt},
6 net::{TcpListener, TcpSocket},
7 runtime::Builder,
8 sync::oneshot,
9};
10
11const TCP_ENDPOINT: &str = "127.0.0.1:8080";
12const NUM_MSGS: usize = 100;
13const MSG_SIZE: usize = 1024;
14
15fn main() {
16 let rt = Builder::new_multi_thread().enable_io().build().unwrap();
17 let rt2 = Builder::new_multi_thread().enable_io().build().unwrap();
18
19 rt.spawn(async {
20 let listener = TcpListener::bind(TCP_ENDPOINT).await.unwrap();
21 let (mut socket, _) = listener.accept().await.unwrap();
22 let (mut rd, mut wr) = socket.split();
23 while tokio::io::copy(&mut rd, &mut wr).await.is_ok() {}
24 });
25
26 // wait a bit so that the listener binds.
27 sleep(Duration::from_millis(100));
28
29 // create a channel to let the main thread know that all the messages were sent and received.
30 let (tx, mut rx) = oneshot::channel();
31
32 rt2.spawn(async {
33 let addr = TCP_ENDPOINT.parse().unwrap();
34 let socket = TcpSocket::new_v4().unwrap();
35 let mut stream = socket.connect(addr).await.unwrap();
36
37 let mut buff = [0; MSG_SIZE];
38 for _ in 0..NUM_MSGS {
39 let one_mega_random_bytes: Vec<u8> =
40 (0..MSG_SIZE).map(|_| rand::random::<u8>()).collect();
41 stream
42 .write_all(one_mega_random_bytes.as_slice())
43 .await
44 .unwrap();
45 stream.read(&mut buff).await.unwrap();
46 }
47 tx.send(()).unwrap();
48 });
49
50 loop {
51 // check that we're done.
52 match rx.try_recv() {
53 Err(oneshot::error::TryRecvError::Empty) => (),
54 Err(oneshot::error::TryRecvError::Closed) => panic!("channel got closed..."),
55 Ok(()) => break,
56 }
57 }
58}
59