Rust 如何从TcpListener上窥视东京tcp流?
我正在使用rustls和hyper编写一个服务器,希望查看并解析TcpStream,然后接受我想要的相应的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更改
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";
}