How to exchange data in a block_on section?

I'm learning Rust and Tokio and I suspect I may be going in the wrong direction.

I'm trying to open a connection to a remote server and perform a handshake. I want to use non-blocking IO so I'm using Tokio's thread pool. The handshake needs to be performed quickly or the remote will close the socket so I'm trying to chain the message exchange in a single block_on section:

let result: Result<(), Box<dyn std::error::Error>> = session.runtime().borrow_mut().block_on(async {
    let startup = startup(session.configuration());
    stream.write_all(startup.as_ref()).await?;

    let mut buffer:Vec<u8> = Vec::new();
    let mut tmp = [0u8; 1];
    loop {
        let total = stream.read(&mut tmp).await;
        /*
        if total == 0 {
            break;
        }
        */
        if total.is_err() {
            break;
        }
        buffer.extend(&tmp);
    }
    Ok(())
});

My problem is what to do when there are no more bytes in the socket to read. My current implementation reads the response and after the last byte hangs, I believe because the socket is not closed. I thought checking for 0 bytes read would be enough but the call to read() never returns.

What's the best way to handle this?

A return of zero bytes indicates that the remote peer has closed the connection. If the connection is still open, read will wait for the peer to send more data.

Generally you should not rely on whether the remote is writing data or not. The connection may just be slow. Look at the data they wrote, and use the contents to determine whether you have received all the data you need.

For background, I'm used to Asio so I may be approaching this the wrong way entirely. Each packet I receive will have a length so I can read_exact but I don't know how many packets will be sent to the socket. How can I check if there's data available?

Well there's now_or_never which you can use on a call to read.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.