Help! I am in trouble when handleing tokio's TcpStream

First run main and then run test.
And then the code will trap in an infinite loop because i handle Ok(0) with nothing,
but if i handle Ok(0) with break, i will get empty request when request is normal.
the introduce of func read:

If n is 0, then it can indicate one of two scenarios:

This reader has reached its "end of file" and will likely no longer be able to produce bytes. Note that this does not mean that the reader will always no longer be able to produce bytes.
The buffer specified was 0 bytes in length.
use std::error::Error;
use tokio::io::AsyncReadExt;
use tokio::net::{TcpListener, TcpStream};

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let listener = TcpListener::bind("127.0.0.1:8080").await?;
    println!("Server listening on 127.0.0.1:8080");

    loop {
        let (stream, _) = listener.accept().await?;
        tokio::spawn(handle_connection(stream));
    }
}

async fn handle_connection(mut stream: TcpStream) {
    let mut buf = Vec::with_capacity(1024);

    loop {
        match stream.read(buf.as_mut_slice()).await {
            Err(e) => {
                eprintln!("Error reading from stream: {}", e);
            }
            Ok(0) => {
                // break;
            }
            Ok(_) => {}
        }

        if buf.ends_with(b"\r\n") {
            break;
        }
    }
}

#[test]
fn test() {
    use std::io::Write;

    let mut a = std::net::TcpStream::connect("www.localhost:8080").unwrap();
    a.write_all(b"").unwrap();
}

Vec::with_capacity creates a vector with a size of 0, so you are passing an empty slice to read. Instead, you can create it like this: let mut buf = vec![0; 1024];.

2 Likes

No matter how many times I've done this mistake, I keep doing it over and over again.

I kind of wish there was a lint for passing a Vec::new() or Vec::with_capacity() immediately (read: without growing the number of elements) to a reader.

1 Like

Yeah, creating a mutable slice immediately from a Vec::with_capacity seems like something that clippy could definitely detect.

1 Like

Thanks