Greetings!
I'm trying to build simple relay server that can connect 2 peers with each-other. One client is a "server" application behind the NAT and another is acting like "client" also behind NAT.
So i took an example from tokio's proxy tutorial and slightly modify it - I added a HashMap where I store TcpStream and id of this stream. When I connect to my relay server with first client, who'll act as listener, I add his id and TcpStream to a HashMap. Then get that TcpStream from a HashMap when second client irrives.
use tokio::io;
use tokio::net::TcpListener;
use tokio::net::TcpStream;
use tokio::select;
use std::collections::HashMap;
pub const LISTEN: u8 = 0;
pub const CLIENT: u8 = 1;
async fn proxy() -> io::Result<()> {
let listener = TcpListener::bind("0.0.0.0:8888".to_string()).await?;
let mut sh_streams = HashMap::new();
loop {
let (stream, _) = listener.accept().await?;
stream.readable().await?;
let mut buf = [0u8;2];
match stream.try_read(&mut buf) {
Ok(n) => {
let id = buf[1];
match buf[0] {
LISTEN => {
sh_streams.insert(id, stream);
}
CLIENT => {
let listener = sh_streams.get_mut(&id).unwrap();
tokio::spawn(async move {
let (mut read, mut write) = stream.into_split();
let (mut read2, mut write2) = listener.into_split();
tokio::select! {
_=io::copy(&mut read,&mut write2)=>{},
_=io::copy(&mut read2, &mut write)=>{}
}
});
}
_ => {}
}
},
Err(e) => {
return Err(e.into());
}
}
}
}
#[tokio::main]
async fn main() -> io::Result<()> {
proxy().await
}
It compiles with error -
--> src/main.rs:29:38
|
29 | ... let (mut read2, mut write2) = listener.into_split();
| ^^^^^^^^^------------
| | |
| | `*listener` moved due to this method call
| move occurs because `*listener` has type `tokio::net::TcpStream`, which does not implement the `Copy` trait
I'm new to rust, so maybe I'm missing something... Please help!