将TCP代理托管到http、ssh和其他TCP流量

将TCP代理托管到http、ssh和其他TCP流量,tcp,server,proxy,rust,Tcp,Server,Proxy,Rust,我是新手,作为一个学习项目,我想创建一个tcp代理。Tokio让我不知所措,我找不到合适的文档来理解它是如何工作的。所以我试着使用std网络模块,但我坚持正确地控制流量。我将多个侦听器绑定到它们自己的线程中,并希望像适当的tcp代理那样来回传输流量。不幸的是,我似乎不明白这在生锈的环境中是如何起作用的。有人能给我一个没有第三方依赖关系的例子吗 这是我的密码。handle\u从接受连接时调用连接 fn forward(direction: &str, input: &mut Buf

我是新手,作为一个学习项目,我想创建一个tcp代理。Tokio让我不知所措,我找不到合适的文档来理解它是如何工作的。所以我试着使用std网络模块,但我坚持正确地控制流量。我将多个侦听器绑定到它们自己的线程中,并希望像适当的tcp代理那样来回传输流量。不幸的是,我似乎不明白这在生锈的环境中是如何起作用的。有人能给我一个没有第三方依赖关系的例子吗

这是我的密码。handle\u从接受连接时调用连接

fn forward(direction: &str, input: &mut BufReader<TcpStream>, output: &mut BufWriter<TcpStream>) {
    loop {
        let mut buffer = [0;1024];
        debug!("{} Reading", direction);
        match input.read(&mut buffer) {
            Ok(bytes) => {
                debug!("Read {} bytes", bytes);
                if bytes < 1  {
                    break;
                }
                match output.write_all(&mut buffer) {
                    Ok(_) => {
                        debug!("Forwarded {:#?} bytes", bytes);
                        output.flush();
                        if bytes < 1024 {
                            break; // abort when everything is sent
                        }
                    },
                    Err(error) => panic!("Could not forward: {}", error)
                }
            },
            Err(error) => panic!("Could not read: {}", error)
        }
    }
}

fn handle_connection(mapping: ProxyMapping, incoming: TcpStream) -> Result<(), String> {
    info!("Incomming connection from {}", incoming.peer_addr().map_err(|e| format!("{}", e))?);
    // Try to connect to target
    let outgoing = TcpStream::connect_timeout(
        &mapping.get_target_addr()?,
        Duration::from_secs(1)
    )?;

    // forward tcp steam
    debug!("Start sync");
    let input_clone = input.try_clone()
        .map_err(|error| format!("Couldn't clone {}", error))?;
    let mut input_read = BufReader::new(input);
    let mut input_write = BufWriter::new(input_clone);

    let output_clone = output.try_clone()
        .map_err(|error| format!("Couldn't clone {}", error))?;
    let mut output_read = BufReader::new(output);
    let mut output_write = BufWriter::new(output_clone);
    debug!("spawn sync");

    loop {
        debug!("Forward");
        forward("forward", &mut input_read, &mut output_write);
        debug!("Backward");
        forward("backward",&mut output_read, &mut input_write);
    }

    Ok(())
}
fn前进(方向:&str,输入:&mut-BufReader,输出:&mut-BufWriter){
环路{
让mut buffer=[0;1024];
调试!(“{}读取”,方向);
匹配输入。读取(&mut缓冲区){
正常(字节)=>{
调试!(“读取{}字节”,字节);
如果字节数小于1{
打破
}
匹配输出。全部写入(&mut缓冲区){
好(41;)=>{
调试!(“转发的{:#?}字节”,字节);
output.flush();
如果字节<1024{
break;//发送所有内容时中止
}
},
Err(error)=>panic!(“无法转发:{}”,错误)
}
},
Err(error)=>panic!(“无法读取:{}”,错误)
}
}
}
fn handle_连接(映射:ProxyMapping,传入:TcpStream)->结果{
信息!(“从{}输入连接”,incoming.peer_addr().map_err(| e | format!(“{}”,e))?);
//尝试连接到目标
let outgoing=TcpStream::connect\u超时(
&mapping.get_target_addr()?,
持续时间:从秒开始(1)
)?;
//前向tcp蒸汽
调试!(“开始同步”);
让input\u clone=input。尝试\u clone()
.map_err(| error | format!(“无法克隆{},错误))?;
让mut input_read=BufReader::new(输入);
让mut input_write=BufWriter::new(input_clone);
让output\u clone=output.try\u clone()
.map_err(| error | format!(“无法克隆{},错误))?;
让mut output_read=BufReader::new(输出);
让mut output_write=BufWriter::new(output_clone);
调试!(“生成同步”);
环路{
调试!(“转发”);
转发(“转发”、&mut输入\读、&mut输出\写);
调试!(“向后”);
正向(“反向”、&mut输出\读取和&mut输入\写入);
}
好(())
}

到目前为止,它代理了一些数据,但对于http请求,它会在反向读取时停止,因为我还不知道何时应该关闭连接。一段时间后,它会将读取的0字节溢出日志。我为同步添加了一个循环,因为一个tcp连接可以发送多个数据包。有什么改进的办法吗?

您有没有找到更好的解决方案?