Search code examples
rusttcprust-tokio

Why does tokio::net::TcpListener connection shut off on its own in Windows?


I am following along a video tutorial on making a basic chat TCP server. The code is simple:

use tokio::{
    io::{AsyncReadExt, AsyncWriteExt}, 
    net::TcpListener,
};

#[tokio::main]
async fn main() {
    let listener = TcpListener::bind("localhost:8080").await.unwrap();

    let (mut socket, _addr) = listener.accept().await.unwrap();
    let mut buffer = [0u8; 1024];
    let bytes_read = socket.read(&mut buffer).await.unwrap();
    socket.write_all(&buffer[..bytes_read]).await.unwrap();
}

When run on a Windows 10 machine, the server allows connection from telnet, but shuts down as soon as I type anything. After messing around, I tried the same code on a Linux machine, and everything works fine.

What could be the issue and is there a way to keep the connection alive on Windows?


Solution

  • Basically what is happening is that telnet on Windows sends each key to the server as soon as it is typed, which causes the server to reply immediately, and as it doesn't not show what is typed, it appears the server is closing the connection on its own without doing anything.

    So there is nothing wrong with the code, but for the sake of accommodating Windows' telnet, the code can be modified to wait for a full line instead:

    let listener = TcpListener::bind("localhost:8080").await.unwrap();
    
    let (socket, _addr) = listener.accept().await.unwrap();
    let mut socket = BufReader::new(socket);
    let mut buffer = String::new();
    socket.write(r" ".as_bytes()).await.unwrap();
    socket.read_line(&mut buffer).await.unwrap();
    if buffer == "exit" {
       break;
    }
    socket.write_all(buffer.as_bytes()).await.unwrap();
    tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;