ssl - SslStream读取不返回客户端的消息
问题描述
我正在尝试使用 TLS (openssl) 实现客户端-服务器应用程序。我按照 rust doc 中给出的示例作为我的代码结构:示例
服务器代码
fn handle_client(mut stream: SslStream<TcpStream>){
println!("Passed in handling method");
let mut data = vec![];
let length = stream.read(&mut data).unwrap();
println!("read successfully; size read:{}", length);
stream.write(b"From server").unwrap();
stream.flush().unwrap();
println!("{}", String::from_utf8_lossy(&data));
}
fn main() {
//remember: certificate should always be signed
let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
acceptor.set_private_key_file("src/keyfile/key.pem", SslFiletype::PEM).unwrap();
acceptor.set_certificate_file("src/keyfile/certs.pem",SslFiletype::PEM).unwrap();
acceptor.check_private_key().unwrap();
let acceptor = Arc::new(acceptor.build());
let listener = TcpListener::bind("127.0.0.1:9000").unwrap();
for stream in listener.incoming(){
match stream{
Ok(stream)=>{
println!("a receiver is connected");
let acceptor = acceptor.clone();
//thread::spawn(move || {
let stream = acceptor.accept(stream).unwrap();
handle_client(stream);
//});
}
Err(_e)=>{println!{"connection failed"}}
}
}
println!("Server");
}
客户代码
fn main() {
let mut connector = SslConnector::builder(SslMethod::tls()).unwrap();
connector.set_verify(SslVerifyMode::NONE); //Deactivated verification due to authentication error
connector.set_ca_file("src/keyfile/certs.pem");
let connector = connector.build();
let stream = TcpStream::connect("127.0.0.1:9000").unwrap();
let mut stream = connector.connect("127.0.0.1",stream).unwrap();
stream.write(b"From Client").unwrap();
stream.flush().unwrap();
println!("client sent its message");
let mut res = vec![];
stream.read_to_end(&mut res).unwrap();
println!("{}", String::from_utf8_lossy(&res));
// stream.write_all(b"client").unwrap();
println!("Client");
}
服务器代码和客户端代码都编译没有问题,尽管有一些警告。客户端能够连接到服务器。但是当客户端将其消息From Client写入流时,在handle_client()中调用 的stream.read什么也不返回。此外,当服务器从服务器写入其消息时,客户端能够接收到该消息。 因此,我使用 SslStream 的方式或配置服务器的方式是否存在问题?
解决方案
我假设当你说stream.read
什么都不返回时,它返回一个零值,表示没有读取任何内容。
Read
特征 API 是这样说的:
这个函数不提供任何关于它是否阻塞等待数据的保证,但是如果一个对象需要阻塞读取并且不能,它通常会通过一个 Err 返回值来发出信号。
如果 n 为 0,则它可以指示以下两种情况之一:
此阅读器已到达其“文件末尾”,可能不再能够生成字节。请注意,这并不意味着阅读器将不再能够生成字节。
指定的缓冲区长度为 0 字节。
如果返回值 n 小于缓冲区大小,则不是错误,即使读取器尚未位于流的末尾。例如,这可能是因为现在实际可用的字节较少(例如接近文件结尾)或因为 read() 被信号中断。
因此,您需要反复调用read
,直到收到您期望的所有字节,否则会出错。
如果您确切知道要读取多少(就像在本例中所做的那样),您可以调用read_exact
which 将准确读取填充提供的缓冲区所需的字节数。
如果您想阅读直到分隔符(例如换行符或其他字符),您可以使用 a BufReader
,它提供诸如read_until
or之类的方法read_line
。
推荐阅读
- ios - 使用较少的半样板设置 UIView(或对象)的多个属性 - Swift
- javascript - 索引格式错误:int() 以 10 为底的无效文字
- node.js - 如何查询令牌并在云功能内发送推送通知?
- java - Wicket IValidator 的错误消息中的链接是否可能?
- reactjs - Nextjs 项目未编译为 ES5
- flutter - Flutter AnimatedList 和 AnimatedController
- mysql - Mysql连接mariadb容器失败
- excel - 如何复制公式结果
- react-bootstrap - 如何删除 react-bootstrap Carousel 动画并使其仅在点击时移动?
- visual-studio-code - VSCode remote-ssh 无法连接到 win server 2019