Home > other >  Rust Single threaded Persistent TCP Server
Rust Single threaded Persistent TCP Server

Time:12-26

I'm trying to make a server in Rust using tcp protocol. I can make a normal server, through the language documentation, but I don't want that whenever a new connection is made, a new thread is created, nor do I want to use a thread pool, because the tcp connections will be persistent, that is, they will last a long time (around 30min-2h). So, I looped over all the connections and, with a 1 millisecond timeout, I try to read if there are any new packets. However, something tells me this is not the right thing to do. Any idea? Thanks in advance.

CodePudding user response:

not sure if this is what you need but you can find in "The Rust Programming Language" Book an example for a single threaded TCP Server. https://doc.rust-lang.org/book/ch20-01-single-threaded.html

Please refer to Listing 20-2:

use std::io::prelude::*;
use std::net::TcpListener;
use std::net::TcpStream;

fn main() {
    let listener = TcpListener::bind("127.0.0.1:7878").unwrap();

    for stream in listener.incoming() {
        let stream = stream.unwrap();

        handle_connection(stream);
    }
}

fn handle_connection(mut stream: TcpStream) {
    let mut buffer = [0; 1024];

    stream.read(&mut buffer).unwrap();

    println!("Request: {}", String::from_utf8_lossy(&buffer[..]));
}

Ref: https://doc.rust-lang.org/book/ch20-01-single-threaded.html#reading-the-request

CodePudding user response:

You are probably looking for some asynchronous runtime. Like most runtimes, tokio can be customized to work with a single thread, if you don't have many connections you centainly don't need more than one. If we translate the example @Benjamin Boortz provided:

use tokio::io::*;
use tokio::net::{TcpListener, TcpStream};

#[tokio::main(flavor = "current_thread")]
async fn main() {
    let listener = TcpListener::bind("127.0.0.1:7878").await.unwrap();
    while let Ok((stream, _address)) = listener.accept().await {
        // this is similar to spawning a new thread.
        tokio::spawn(handle_connection(stream));
    }
}

async fn handle_connection(mut stream: TcpStream) {
    let mut buffer = [0; 1024];
    stream.read(&mut buffer).await.unwrap();
    println!("Request: {}", String::from_utf8_lossy(&buffer[..]));
}

This code is concurrent, yet single threaded, which seems to be what you want. I recommend you check the tokio tutorial. It is a really good resource if you are unfamiliar with asynchronous programming in Rust.

  • Related