简体   繁体   English

rust 非阻塞 openssl stream

[英]rust non blocking openssl stream

Trying to create a non blocking ssl stream:尝试创建非阻塞 ssl stream:

use openssl::ssl::{SslMethod, SslConnector};
use std::io::{Read, Write};
use std::net::TcpStream;

let connector = SslConnector::builder(SslMethod::tls()).unwrap().build();

let stream = TcpStream::connect("google.com:443").unwrap();
stream.set_nonblocking(true);
let mut stream = connector.connect("google.com", stream).unwrap();

But I got this error:但我得到了这个错误:

thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value:WouldBlock(MidHandshakeSslStream { stream: SslStream { stream: TcpStream { addr:V4(10.137.0.17:55628), peer: V4(172.217.21.78:443), fd: 3 }, ssl: Ssl { state: "SSLv3/TLSwrite client hello", verify_result: X509VerifyResult { code: 0, error: "ok" } } }, error: Error { code: ErrorCode(2), cause: Some(Io(Os { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" })) } })', src/libcore/result.rs:1051:5 

How can I create a non blocking ssl stream?如何创建非阻塞 ssl stream?

The tokio project has tokio-openssl crate. tokio 项目有tokio-openssl crate。 You probably need to embrace the whole async/await machinery and use that crate to do nonblocking openssl:您可能需要接受整个async/await机制并使用该板条箱来执行非阻塞 openssl:

//# openssl = "0.10.25"
//# tokio = "0.2.0-alpha.6"
//# tokio-net = "0.2.0-alpha.6"
//# tokio-openssl = "0.4.0-alpha.6"
use openssl::ssl::{SslMethod, SslConnector};
use tokio::net::TcpStream;
use tokio::prelude::*;
use tokio_net::driver::Handle;
use tokio_openssl::connect;
use std::error::Error;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let sslconf = SslConnector::builder(SslMethod::tls())?
        .build()
        .configure()?;
    // The following 3 lines are equivalent to:
    //     let stream = TcpStream::connect("google.com:443").await?;
    // It's just going to show that the socket is indeed nonblocking.
    let stream = std::net::TcpStream::connect("google.com:443")?;
    stream.set_nonblocking(true)?;
    let stream = TcpStream::from_std(stream, &Handle::default())?;
    let mut stream = connect(sslconf, "google.com", stream).await?;

    stream.write_all(b"GET / HTTP/1.0\r\n\r\n").await?;
    let mut res = vec![];
    stream.read_to_end(&mut res).await?;
    dbg!(String::from_utf8_lossy(&res));

    Ok(())
}

Of course this also means that for now you'll have to use beta/nightly channel.当然,这也意味着现在你必须使用 beta/nightly 频道。 It may or may not work out for your project.它可能适用于您的项目,也可能不适用于您的项目。

If a non blocking stream is needed but you don't want to add tokio as dependency a possible solution is:如果需要非阻塞 stream 但您不想添加 tokio 作为依赖项,则可能的解决方案是:

use openssl::ssl::{SslMethod, SslConnector};
use std::io::{Read, Write};
use std::net::TcpStream;

let connector = SslConnector::builder(SslMethod::tls()).unwrap().build();

let stream = TcpStream::connect("google.com:443").unwrap();
let mut stream = connector.connect("google.com", stream).unwrap();
let inner_stream = stream.get_ref();
inner_stream.set_nonblocking(true);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM