0

I would like to set a generic value (n) in the array based on the bytes that are written in the stream. Now I do not know the exact length of the buffer, I just create a hard coded array to read the stream bytes.

use mio::net::TcpStream;

...
let mut buf = [0;12];
stream.read_exact(&mut buf).unwrap();

I would like to swap the 12 hard coded length for a bytes length (n), any clues?

DustInTheSilence
  • 575
  • 1
  • 7
  • 15
  • If you need a runtime length, don't use arrays, they are stack allocated and thus must have a length fixed at compile-time. Create a vec of the correct size instead. – Masklinn Mar 14 '23 at 11:57
  • using array or vector is not the case. I would like to get the length of the bytes that are written in the stream – DustInTheSilence Mar 14 '23 at 12:02
  • The return value of the [`Read::read`](https://doc.rust-lang.org/std/io/trait.Read.html#tymethod.read) method is the number of bytes written to the buffer. Same goes for [`Read::read_to_end`](https://doc.rust-lang.org/std/io/trait.Read.html#method.read_to_end). Maybe use one of these two in favour of `read_exact`? – Jonas Fassbender Mar 14 '23 at 12:04
  • Do you mean you want to know how many bytes are available? I don't think there's a way to do that, at least not in standard Rust. – Chayim Friedman Mar 14 '23 at 12:05
  • 1
    I don't understand your question. – Chayim Friedman Mar 14 '23 at 12:07
  • I would like to read the available (written) bytes in the stream. For example if the server writes in the stream "Hello StackOverflow", creating an array of length 12 in the client, I would get "Hello StackO" and not the whole message. Is it a way to do? – DustInTheSilence Mar 14 '23 at 12:16
  • 1
    So do you want to read all data in the stream? You need to create a `Vec` and append to it until you meat EOF. Luckily, there is [`std::io::Read::read_to_end()`](https://doc.rust-lang.org/stable/std/io/trait.Read.html#method.read_to_end). However, it won't work in your case because you're working with non-blocking streams (`mio`). Not that I understand why you work directly with `mio` and not with `tokio`. – Chayim Friedman Mar 14 '23 at 12:18
  • because I am playing around and I am trying to understand rust so, all kind of suggestions are welcome as yours. ;) – DustInTheSilence Mar 14 '23 at 12:22
  • 2
    So just use `tokio`. `mio` is intended for low-level cases where you need exact control. [`tokio` also has (async) `read_to_end()`](https://docs.rs/tokio/latest/tokio/io/trait.AsyncReadExt.html#method.read_to_end). – Chayim Friedman Mar 14 '23 at 12:23

1 Answers1

2

Use Read::read_to_end(). It won't work with non-blocking streams, but just use tokio. Example of using tokio's read_to_end():

async fn read_to_end(stream: &mut tokio::net::TcpStream) -> Vec<u8> {
    use tokio::io::AsyncReadExt;
    
    let mut data = Vec::new();
    stream.read_to_end(&mut data).await.expect("read failed");
    data
}
Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77