Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

echo client in Echo server section hangs #754

Closed
akhi3030 opened this issue Mar 5, 2024 · 3 comments
Closed

echo client in Echo server section hangs #754

akhi3030 opened this issue Mar 5, 2024 · 3 comments

Comments

@akhi3030
Copy link
Contributor

akhi3030 commented Mar 5, 2024

I am not sure if this my own bug; expected behaviour; or something can be improved in the tutorial.

When I run the client code reproduced below, the process hangs. I would've expected it to exit after receiving all the payload.

use tokio::io::{self, AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpStream;

#[tokio::main]
async fn main() -> io::Result<()> {
    let socket = TcpStream::connect("127.0.0.1:6142").await?;
    let (mut rd, mut wr) = io::split(socket);

    // Write data in the background
    tokio::spawn(async move {
        wr.write_all(b"hello\r\n").await?;
        wr.write_all(b"world\r\n").await?;

        // Sometimes, the rust type inferencer needs
        // a little help
        Ok::<_, io::Error>(())
    });

    let mut buf = vec![0; 128];

    loop {
        let n = rd.read(&mut buf).await?;

        if n == 0 {
            break;
        }

        println!("GOT {:?}", &buf[..n]);
    }

    Ok(())
}

Output:

GOT [104, 101, 108, 108, 111, 13, 10, 119, 111, 114, 108, 100, 13, 10]

I would've naively thought that when the writing task above returns, that will close the socket for writing but still keep it open for reading. At least on linux, this can be accomplished by using shutdown. This will cause the echo server to get an EOF when it tries to read from the socket and cause it to close the socket which will then cause the client to see n == 0 condition when it calls reads; break; and then the process would exit.

Maybe this is not io::split works. The smallest change to make might be to add a note to the tutorial to indicate that the client does not exit. A more involved change might be see how to get the client to properly exit.

@Darksonn
Copy link
Contributor

Darksonn commented Mar 6, 2024

Indeed, io::split does not work in that way. You must explicitly call shutdown to close it.

@wakuflair
Copy link

Hi I am a newbie of Tokio and also stuck in this issue.
shutdown indeed avoid hangs, but what I am trying to do is an echo client that can repeatedly send and receive bytes, the pseudo code is like:

  1. read a line from stdin
  2. send it to the echo server
  3. receive the eco and print it to stdout
  4. go back to 1

I need to reuse the writer so I can't use shutdown , what should I do?

@Darksonn
Copy link
Contributor

Darksonn commented Mar 9, 2024

This is not the right place to ask for help. Please find the links at the bottom of this page and ask there.

@Darksonn Darksonn closed this as not planned Won't fix, can't repro, duplicate, stale Mar 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants