DEV Community

BC
BC

Posted on

2 1

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

👋 While you are here

Reinvent your career. Join DEV.

It takes one minute and is worth it for your career.

Get started

Top comments (0)

👋 Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay