SslStream<TcpStream> 读取不 return 客户端的消息

SslStream<TcpStream> read does not return client's message

我正在尝试使用 TLS (openssl) 实现客户端-服务器应用程序。我遵循了 rust 文档中给出的代码结构示例:example
服务器代码

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 写入流时, stream.read[=37= 中调用]() returns 没什么。此外,当服务器写入其消息 From Server 时,客户端能够接收到该消息。 因此,我使用 SslStream 的方式或配置服务器的方式是否存在问题

我假设当你说 stream.read returns 什么都没有时,它 returns 一个零值表示没有读取任何内容。

Read 特征 API 是这样说的:

This function does not provide any guarantees about whether it blocks waiting for data, but if an object needs to block for a read and cannot, it will typically signal this via an Err return value.

If n is 0, then it can indicate one of two scenarios:

  • This reader has reached its "end of file" and will likely no longer be able to produce bytes. Note that this does not mean that the reader will always no longer be able to produce bytes.

  • The buffer specified was 0 bytes in length.

It is not an error if the returned value n is smaller than the buffer size, even when the reader is not at the end of the stream yet. This may happen for example because fewer bytes are actually available right now (e. g. being close to end-of-file) or because read() was interrupted by a signal.

因此,您需要重复调​​用read,直到收到所有您期望的字节,否则会出现错误。

如果您确切知道要读取多少(就像您在本例中所做的那样),您可以调用 read_exact 它将准确读取填充提供的缓冲区所需的字节数。

如果您想读到一个定界符(例如换行符或其他字符),您可以使用 BufReader, which provides methods such as read_until or read_line.