46 lines
1.6 KiB
Rust
46 lines
1.6 KiB
Rust
use tokio::net::TcpListener;
|
|
|
|
// TODO: write an echo server that accepts incoming TCP connections and
|
|
// echoes the received data back to the client.
|
|
// `echo` should not return when it finishes processing a connection, but should
|
|
// continue to accept new connections.
|
|
//
|
|
// Hint: you should rely on `tokio`'s structs and methods to implement the echo server.
|
|
// In particular:
|
|
// - `tokio::net::TcpListener::accept` to process the next incoming connection
|
|
// - `tokio::net::TcpStream::split` to obtain a reader and a writer from the socket
|
|
// - `tokio::io::copy` to copy data from the reader to the writer
|
|
pub async fn echo(listener: TcpListener) -> Result<(), anyhow::Error> {
|
|
todo!()
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
|
|
|
#[tokio::test]
|
|
async fn test_echo() {
|
|
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
|
let addr = listener.local_addr().unwrap();
|
|
tokio::spawn(echo(listener));
|
|
|
|
let requests = vec!["hello", "world", "foo", "bar"];
|
|
|
|
for request in requests {
|
|
let mut socket = tokio::net::TcpStream::connect(addr).await.unwrap();
|
|
let (mut reader, mut writer) = socket.split();
|
|
|
|
// Send the request
|
|
writer.write_all(request.as_bytes()).await.unwrap();
|
|
// Close the write side of the socket
|
|
writer.shutdown().await.unwrap();
|
|
|
|
// Read the response
|
|
let mut buf = Vec::with_capacity(request.len());
|
|
reader.read_to_end(&mut buf).await.unwrap();
|
|
assert_eq!(&buf, request.as_bytes());
|
|
}
|
|
}
|
|
}
|