Copy Reader/Writer to/from TcpStream

Hi,

I have the following code:

    let mut chan: Reader + Writer = ???

    let mut tcp_remote = TcpStream::connect("rpi4:80").unwrap();

    let mut tcp_remote_cp = tcp_remote.try_clone().unwrap();

    let r = thread::spawn(move || {
        std::io::copy(&mut chan, &mut tcp_remote_pc)
    });

    std::io::copy(&mut tcp_remote, &mut chan).unwrap();

Of course this does not compile, because chan cannot be moved into the new thread.

Is there a way I can somehow split chan and pass only the Reader part to the thread? chan is a ssh2 Channel, which doesn't offer any split method. I cannot wrap in an Arc, because I need a mutable reference.

I think maybe have some type of a communication channel between the threads and have only one thread reading/writing from the channel?

What would be the rust way to copy the Channel to/from the tcp stream?

Thank you

You are looking for Arc<Mutex<_>>, then.

I did try that, but then my code deadlocks. I believe because there is only a mutex for both Reader and Writer and both of the sides lock waiting for the mutex when I run two copies? Maybe I am doing something wrong here.

A mutex certainly wont help. It will deadlock.

Unfortunately, I don't think there's any way to easily fix your code. Some readers/writers (e.g. tcp stream) work even with immutable references, so if you have one of those, then an Arc would do it. But if you don't, then I don't think you can do what you're trying to do with the way that the library is shaped.

Note that this would be quite easy to do if your code was async. There, any IO resource can be split.

1 Like

Unfortunately, I don't think there's any way to easily fix your code

Is there a hard way to fix it? :wink:

I get a sync Channel from a library, is there a way to convert a Read + Write to AsyncRead + AsyncWrite and then split it?

I don't see anything in ssh2 that allows you to both read and write from an ssh2::Stream at the same time. Unfortunately, I think you would have to switch to an entirely different library.

Maybe channel.read_window().available could be used to check if there is any data available to read? Based on the docs channel.wait_eof() seems to be allow waiting on either EOF or any data becoming available.

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.