Is there any way to read and write a TcpStream at the same time?

When I develop a transfer program by Rust, I cannot find a way to read and write the same TcpStream object at the same time - I cannot use its input stream and output stream in two threads. That means I cannot download and upload data at the same time as fast as possible. Am I missing something to use?

You will need something to sync access to the shared resource between threads. The simplest tool for the job would be to wrap the stream in a mutex and share that between your 2 threads.

let stream = Arc::new(Mutex::new(TcpStream::::connect(ip)?));

But anything in mutex can only be used by one. I still cannot use the stream for both reading and writing at the same time. When the reading thread read from the stream, the writing stream has to wait for it. And that is hard to build a sustainable loop.

There's a method on TcpStream I didn't know, try_clone, which should do what you want.

let reader_stream = TcpStream::::connect(ip)?;
let writer_stream = reader_stream.try_clone()?;
1 Like

Maybe it works. But TcpStream is a read-and-write stream, If I read or write data at both of them, result is not clear yet.

You can read or write to a TcpStream using only immutable access, so you can simply put it in an Arc without the Mutex.

Like this?

let stream = Arc::new(tcp_stream);

But both read and write method need mutable reference.

No they don't. There are implementations of Read and Write for &TcpStream too. You can get an &mut &TcpStream with only immutable access to the stream.

5 Likes

:star_struck:

let stream_ref = &mut &TcpStream;
stream_ref.write(...);
stream_ref.read(...);

?

Sort of. But according to the docs TcpStream in std::net - Rust you need to get a TcpStream from an accept or connect call:

After creating a TcpStream by either connect ing to a remote host or accept ing a connection on a TcpListener , data can be transmitted by reading and writing to it.

And the example there shows how:

use std::io::prelude::*;
use std::net::TcpStream;

fn main() -> std::io::Result<()> {
    let mut stream = TcpStream::connect("127.0.0.1:34254")?;

    stream.write(&[1])?;
    stream.read(&mut [0; 128])?;
    Ok(())
} // the stream is closed here

I know that~

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.