Rust 如何从TcpListener上窥视东京tcp流?

Rust 如何从TcpListener上窥视东京tcp流?,rust,rust-tokio,hyper,Rust,Rust Tokio,Hyper,我正在使用rustls和hyper编写一个服务器,希望查看并解析TcpStream,然后接受我想要的相应的tokio_rustls::TlsAceptor。然而,这导致我在流上同时使用异步和非异步函数(tokio::net::TcpStream::peek和tokio_rustls::TlsAceptor::accept),这给我带来了麻烦。只需为peek函数添加一个异步块,我就会得到一个“必须使用的`core::future::future::future`未使用的实现者”错误,将move更改

我正在使用rustls和hyper编写一个服务器,希望查看并解析TcpStream,然后接受我想要的相应的
tokio_rustls::TlsAceptor
。然而,这导致我在流上同时使用异步和非异步函数(
tokio::net::TcpStream::peek
tokio_rustls::TlsAceptor::accept
),这给我带来了麻烦。只需为
peek
函数添加一个异步块,我就会得到一个
“必须使用的`core::future::future::future`未使用的实现者”
错误,将
move
更改为
async move
不起作用

我想知道是否有办法绕过这个问题,也许不使用
和_then()

//依赖项:futures util=“0.3.1”,rustls=“0.18”
//tokio={version=“0.2”,功能=[“full”]},tokio rustls=“0.14.0”
使用tokio::net::{TcpListener,TcpStream};
使用tokio_rustls::server::TlsStream;
使用tokio_rustls::TlsAceptor;
使用std::{sync,io};
使用futures\u util::{
future::TryFutureExt,
流::{StreamExt,trysteamext},
};
#[tokio::main]
异步fn运行\u服务器()->结果{
设addr=format!(“127.0.0.1:{}”,8000);
让mut-tcp=TcpListener::bind(&addr).wait?;
让tls_config=sync::Arc::new(rustls::ServerConfig::new(rustls::noclientututh::new());
让tls_acceptor=TlsAcceptor::from(tls_config);
让mut v=vec![0u8;16*1024];
//主要问题焦点
让传入的\u tls\u流=tcp
.incoming()
.map_err(| e | error(format!(“传入失败:{:?}”,e)))
.然后|移动| mut s:TcpStream |{
让n:usize=s.peek(&mut v).wait.unwrap();
println!(“{:}”,n);
//从流中解析某物
让parsed=做某事(&v[…n]);
println!(“{:}”,已解析);
tls_acceptor.accept(s).map_err(| e |{
println!(“客户端连接错误…”);
错误(格式!(“TLS错误:{:?}”,e))
})
})
.boxed();
// ...
返回Ok(());
}
fn main(){
如果让Err(e)=运行_服务器(){
eprintln!(“失败:{}”,e);
std::process::exit(1);
}
}
fn错误(错误:字符串)->io::错误{
io::Error::new(io::ErrorKind::Other,err)
}
fn do_something(字节:&[u8])->&str{
返回“测试”;
}

但未使用
async
块。它不是由闭包返回的,也不会使用它生成的任何内容。@PeterHall你是对的,但我不确定如何正确使用该块,或者它是否是解决我的问题的最佳方法。编辑代码以简化我的问题。您还有其他问题,例如跨异步边界共享
v
s
。是的,共享s正是我要解决的问题。然后您需要使这些变量可共享。e、 g.用
圆弧将其包裹起来。或者强制任务在具有的同一线程中运行。但是不使用
async
块。它不是由闭包返回的,也不会使用它生成的任何内容。@PeterHall你是对的,但我不确定如何正确使用该块,或者它是否是解决我的问题的最佳方法。编辑代码以简化我的问题。您还有其他问题,例如跨异步边界共享
v
s
。是的,共享s正是我要解决的问题。然后您需要使这些变量可共享。e、 g.用
圆弧将其包裹起来。或者强制任务在同一线程中运行,并使用。
// Dependencies: futures-util = "0.3.1", rustls = "0.18"
// tokio = {version = "0.2", features = ["full"]}, tokio-rustls = "0.14.0"
use tokio::net::{TcpListener, TcpStream};
use tokio_rustls::server::TlsStream;
use tokio_rustls::TlsAcceptor;
use std::{sync, io};
use futures_util::{
    future::TryFutureExt,
    stream::{StreamExt, TryStreamExt},
};

#[tokio::main]
async fn run_server() -> Result<(), Box<dyn std::error::Error + Send + Sync>>{
    let addr = format!("127.0.0.1:{}", 8000);
    let mut tcp = TcpListener::bind(&addr).await?;

    let tls_config = sync::Arc::new(rustls::ServerConfig::new(rustls::NoClientAuth::new()));
    let tls_acceptor = TlsAcceptor::from(tls_config);

    let mut v = vec![0u8; 16 * 1024];

    // main focus of question
    let incoming_tls_stream = tcp
        .incoming()
        .map_err(|e| error(format!("Incoming failed: {:?}", e)))
        .and_then(move |mut s: TcpStream| {
            let n: usize = s.peek(&mut v).await.unwrap();
            println!("{:}", n);
            // parse something from stream
            let parsed = do_something(&v[..n]);
            println!("{:}", parsed);

            tls_acceptor.accept(s).map_err(|e| {
                println!("Client-connection error...");
                error(format!("TLS Error: {:?}", e))
            })
        })
        .boxed();

    // ...
    return Ok(());
}

fn main() {
    if let Err(e) = run_server() {
        eprintln!("FAILED: {}", e);
        std::process::exit(1);
    }
}

fn error(err: String) -> io::Error {
    io::Error::new(io::ErrorKind::Other, err)
}

fn do_something(bytes: &[u8]) -> &str {
    return "test";
}