UnixStream write/read 完整字符串

UnixStream write/read full string

我有一个问题的小示例版本:

#[test]
fn streams() {
    use std::io::prelude::*;
    use std::net::Shutdown;
    use std::os::unix::net::UnixStream;
    use std::time::Duration;

    let (mut s1, mut s2) = UnixStream::pair().unwrap();
    s1.write_all(b"hello world").unwrap();
    // Problem is that if not calling shutdown message never arrives
    s1.shutdown(Shutdown::Write).unwrap();
    let mut response = String::new();
    s2.read_to_string(&mut response).unwrap();
    assert_eq!("hello world".to_string(), response);
}

Playground link

我需要关闭连接,否则消息永远不会到达。 我认为问题是 write_all 不写 EOF,所以当使用 read_to_string 时挂起。

例如在python中我会简单地使用:

socket.sendall(message.encode())
data = socket.recv(1024)

发送和接收回复。

我怎样才能用 rust 实现同样的效果?

提前致谢。

read_to_string的语义是:

Read all bytes until EOF in this source, appending them to buf.

If successful, this function returns the number of bytes which were read and appended to buf.

所以如果你不关闭流它就会挂起。您想改用 read

    let (mut s1, mut s2) = UnixStream::pair().unwrap();
    s1.write_all(b"hello world").unwrap();
    let mut buf = [0; 1024];
    let count = s2.read(&mut buf).unwrap();
    let response = String::from_utf8(buf[..count].to_vec()).unwrap();
    assert_eq!("hello world".to_string(), response);

@edwardw 的解释让我意识到我应该知道消息的大小或关闭连接。但是我找到了另一种更适合我需要的方法,从这个 :

中获取了非常有趣的信息
    let (mut s1, mut s2) = UnixStream::pair().unwrap();
    s1.write_all(b"hello world").unwrap();
    let mut buff = [0; 1024];
    let mut h = s2.take(1024);
    h.read(&mut buff);
    let mut response = String::from_utf8(buff.to_vec()).unwrap();
    let res = response.trim_end_matches(char::from(0));
    assert_eq!("hello world".to_string(), res);

在某些情况下这可能是最糟糕的,但现在可以了。只是让流读取最多 1024 个字节,然后只是从字符串中修剪我不需要的内容。