DEV Community

BC
BC

Posted on

Day29:an echo server with tokio - 100DayOfRust

Tokio provides asynchronous runtime which you can spawn tasks into runtime, the runtime will schedule them to run. It is similar to how Golang run goroutines. This makes writing fast and reliable network applications easy in Rust.

In the previous post, I wrote how to use thread pool in Rust with the threadpool crate. With tokio, we don't need to worry about how to assign tasks to thread pool, tokio's runtime will automatically schedule them for us.

Task Scheduler

... the basic_scheduler configuration will block the current thread and process all spawned tasks in place. The threaded_scheduler configuration uses a work-stealing thread pool and distributes load across multiple threads. The threaded_scheduler is the default for applications and the basic_scheduler is the default for tests.

Echo Server

Write a multi-thread + async echo server with Tokio.

In Cargo.toml:

[dependencies]
tokio = { version = "0.2", features = ["full"] }
Enter fullscreen mode Exit fullscreen mode

In main.rs:

use std::error::Error;

use tokio::io::copy;
use tokio::net::TcpListener;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let addr = "127.0.0.1:6143";
    let mut listener = TcpListener::bind(addr).await?;
    println!("Listen on {}", addr);
    loop {
        let (mut sock, _) = listener.accept().await?;
        tokio::spawn(async move {
            let (mut reader, mut writer) = sock.split();
            copy(&mut reader, &mut writer).await.unwrap();
        });
    }
}
Enter fullscreen mode Exit fullscreen mode

In the code we first bind the listen port, and in the loop once we accepted a client connection, we use tokio::spawn to put an async task to tokio's runtime. In the task we read bytes from client and send the same bytes to client (copy bytes from reader to writer). Thanks to tokio, with only around 10 lines code, now we have a fast, multi-thread, async echo server.

Now let's test it. We can run the code in terminal:

$ cargo run
Listen on 127.0.0.1:6143
Enter fullscreen mode Exit fullscreen mode

Now open another terminal to use telnet connect to our server:

$ telnet 127.0.0.1 6143
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
echo
echo
asdf
asdf
Enter fullscreen mode Exit fullscreen mode

We typed "echo" then we got "echo" back, we typed "asdf" then we got "asdf" back. The echo server works!

Reference

Top comments (0)