# Beginner's Guide to Concurrent Programming: Coding a Multithreaded Chat Server using Tokio
_04 May 2024 · #rust · #async · #concurrency · #tokio_

Table of contents
[Introduction](#introduction)
[01\) Simplest possible echo server](#01-simplest-possible-echo-server)
[02\) Handling multiple connections serially](#02-handling-multiple-connections-serially)
[03\) Modifying messages](#03-modifying-messages)
[04\) Parsing a stream of bytes as lines](#04-parsing-a-stream-of-bytes-as-lines)
[05\) Adding `/help` & `/quit` server commands](#05-adding-help--quit-server-commands)
[06\) Handling multiple connections concurrently](#06-handling-multiple-connections-concurrently)
[07\) Letting users kinda chat](#07-letting-users-kinda-chat)
[08\) Letting users actually chat](#08-letting-users-actually-chat)
[09\) Assigning names to users](#09-assigning-names-to-users)
[10\) Letting users edit their names with `/name`](#10-letting-users-edit-their-names-with-name)
[11\) Freeing user's name if they disconnect](#11-freeing-users-name-if-they-disconnect)
[12\) Adding a main room](#12-adding-a-main-room)
[13\) Letting users join or create rooms with `/join`](#13-letting-users-join-or-create-rooms-with-join)
[14\) Listing all rooms with `/rooms`](#14-listing-all-rooms-with-rooms)
[15\) Removing empty rooms](#15-removing-empty-rooms)
[16\) Listing users in the room with `/users`](#16-listing-users-in-the-room-with-users)
[17\) Optimizing performance](#17-optimizing-performance)
[18\) Finishing touches](#18-finishing-touches)
[Conclusion](#conclusion)
[Discuss](#discuss)
[Further reading](#further-reading)
[Notifications](#notifications)
## Introduction
I recently finished coding a multithreaded chat server using Tokio and I'm pretty happy with it. I'd like to share what I learned in this easy-to-follow step-by-step tutorial-style article. Let's get into it.
> [!NOTE]
> The full source code for every step can be found in [the examples directory](https://github.com/pretzelhammer/chat-server/tree/main/examples) of [this repository](https://github.com/pretzelhammer/chat-server).
## 01\) Simplest possible echo server
Let's start by writing the simplest possible echo server.
```rust
use tokio::{io::{AsyncReadExt, AsyncWriteExt}, net::TcpListener};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let server = TcpListener::bind("127.0.0.1:42069").await?;
let (mut tcp, _) = server.accept().await?;
let mut buffer = [0u8; 16];
loop {
let n = tcp.read(&mut buffer).await?;
if n == 0 {
break;
}
let _ = tcp.write(&buffer[..n]).await?;
}
Ok(())
}
```
`#[tokio::main]` is a procedural macro that removes some of the boilerplate of building a tokio runtime, and turns this:
```rust
#[tokio::main]
async fn my_async_fn() {
todo!()
}
```
Roughly into this:
```rust
fn main() {
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap()
.block_on(my_async_fn)
}
async fn my_async_fn() {
todo!()
}
```
And as a quick refresher if we have an async function like this:
```rust
async fn my_async_fn(t: T) -> T {
todo!()
}
```
It roughly desugars into:
```rust
fn my_async_fn(t: T) -> impl Future