1pub mod dkubiszewski {
25 use std::{
26 io::{Read, Write},
27 net::TcpListener,
28 thread,
29 };
30
31 pub struct TcpEcho {
32 chunk_size: usize,
33 port: usize,
34 }
35
36 impl TcpEcho {
37 pub fn new(port: usize, chunk_size: usize) -> Self {
38 Self {
39 port: port,
40 chunk_size: chunk_size,
41 }
42 }
43
44 pub fn serve(&self) {
45 self.serve_with_peek(|_: &[u8]| {});
46 }
47
48 pub fn serve_with_peek(&self, fn_peek: fn(&[u8])) {
49 println!("Starting...");
50 let listener = TcpListener::bind(format!("127.0.0.1:{}", self.port)).unwrap();
51 println!("Started.");
52 let mut connection_counter = 0;
53 for stream in listener.incoming() {
54 connection_counter += 1;
55 println!("Open new connection: {}", connection_counter);
57 let mut stream = stream.unwrap();
58 let mut buffer = vec![0u8; self.chunk_size];
59 thread::spawn(move || loop {
60 let mut write_size = 0;
61 let read_size = stream.read(&mut buffer).unwrap();
62 if read_size == 0 {
63 println!(
64 "No more data to read closing connection: {}",
65 connection_counter
66 );
67 break;
68 }
69 fn_peek(&buffer[..read_size]);
70
71 while write_size < read_size {
72 write_size += stream.write(&buffer[..read_size - write_size]).unwrap();
73 }
74 });
75 }
76 }
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use std::{
83 io::{Read, Write},
84 net::TcpStream,
85 thread,
86 };
87
88 use crate::dkubiszewski::TcpEcho;
89
90 #[test]
91 fn send_receive() {
92 let sut = TcpEcho::new(5555, 1024);
93
94 thread::spawn(move || {
95 sut.serve();
96 });
97
98 let mut test_stream = TcpStream::connect("localhost:5555").unwrap();
99
100 let test_data: [u8; 4] = [0x10, 0x9, 0x3, 0x1];
101 assert_eq!(test_data.len(), test_stream.write(&test_data).unwrap());
102 let mut result_data = [0; 4];
103 assert_eq!(test_data.len(), test_stream.read(&mut result_data).unwrap());
104
105 assert_eq!(result_data, test_data);
106 }
107
108 #[test]
109 fn send_receive_multiple_chunks() {
110 let sut = TcpEcho::new(5556, 1024);
111
112 thread::spawn(move || {
113 sut.serve();
114 });
115
116 let mut test_stream = TcpStream::connect("localhost:5556").unwrap();
117
118 let test_data2 = [
119 [0x10u8, 0x9, 0x3, 0x1],
120 [0x9u8, 0x8, 0x2, 0x0],
121 [0x11u8, 0xa, 0x4, 0x2],
122 ];
123 for test_data in test_data2 {
124 assert_eq!(test_data.len(), test_stream.write(&test_data).unwrap());
125 let mut result_data = vec![0u8; test_data.len()];
126 assert_eq!(test_data.len(), test_stream.read(&mut result_data).unwrap());
127
128 assert_eq!(result_data, test_data);
129 }
130 }
131
132 #[test]
133 fn send_receive_multiple_connections() {
134 let sut = TcpEcho::new(5557, 1024);
135
136 thread::spawn(move || {
137 sut.serve();
138 });
139
140 let test_data2 = [
141 [0x10u8, 0x9, 0x3, 0x1],
142 [0x9u8, 0x8, 0x2, 0x0],
143 [0x11u8, 0xa, 0x4, 0x2],
144 ];
145
146 for test_data in test_data2 {
147 let mut test_stream = TcpStream::connect("localhost:5557").unwrap();
148
149 assert_eq!(test_data.len(), test_stream.write(&test_data).unwrap());
150 let mut result_data = [0; 4];
151 assert_eq!(test_data.len(), test_stream.read(&mut result_data).unwrap());
152
153 assert_eq!(result_data, test_data);
154 }
155 }
156}