rusttcplistenerunsafesingle-threaded

Rust: Safe single-threaded TCP Server


is it possible in pure rust to write a single-threaded TCP Server? In C I would use the select syscall to "listen" to multiple sockets. I only find solutions where people use unsafe to use epoll/select, but I really want to avoid this. I think this is a basic task and I cant imagine that there is no pure rust solution to solve such a task. Basically I am looking for an abstraction in the standard library.

Here is what I want in C: https://www.gnu.org/software/libc/manual/html_node/Server-Example.html

E.g. using unsafe with select/epoll: https://www.zupzup.org/epoll-with-rust/index.html


Solution

  • I ended up using async/await. In this example is not proper error handling.

    use async_std::net::TcpListener;
    use async_std::task;
    use async_tungstenite::accept_async;
    use futures::{
        SinkExt,
        StreamExt,
    };
    use std::net::SocketAddr;
    use std::str::FromStr;
    
    
    async fn run() {
        let addrs = [
            SocketAddr::from_str("0.0.0.0:9001").unwrap(),
            SocketAddr::from_str("[::]:9001").unwrap()];
        let listener = TcpListener::bind(&addrs[..]).await.unwrap();
    
        listener.incoming().for_each_concurrent(None, |stream| async move {
            let mut websocket = accept_async(stream.unwrap()).await.unwrap();
            loop {
                let msg = websocket.next().await.unwrap().unwrap();
                println!("Received {}", msg);
                if msg.is_binary() || msg.is_text() {
                    websocket.send(msg).await.unwrap();
                }
            }
        }).await;
    }
    
    
    fn main () {
        task::block_on(run());
    }