为什么从Unix套接字读取时使用netcat发送^ D不会触发EOF?

时间:2018-12-05 14:49:26

标签: sockets unix rust

我正在尝试编写一个将从Unix套接字读取的服务器:

use std::io::prelude::*;
use std::os::unix::net::{UnixListener, UnixStream};

fn main() {
    let socket_name = "socket";

    let listener = match UnixListener::bind(&socket_name) {
        Err(err) => panic!("Failed to bind to socket: {}.", err),
        Ok(stream) => stream,
    };

    for mut stream in listener.incoming() {
        match stream {
            Ok(ref mut stream) => {
                let msg = read(stream);
                stream.write_all(msg.as_bytes()).expect("Echo");
            }
            Err(err) => panic!("Error occured when listening from the stream. {}", err),
        }
    }

    fn read(stream: &mut UnixStream) -> String {
        let mut s = String::new();
        stream.read_to_string(&mut s).unwrap();
        s
    }
}

playground

在客户端,我使用ncnc -U socket。我发送一些数据并以 ^ D 结尾,它应该是EOF。 read_to_string的文档说:

  

读取所有字节,直到此源中的EOF为止,然后将其附加到buf

预期的行为: 在客户端发送 ^ D 后,服务器将以echo响应

观察到的行为: 服务器无法识别EOF已发送并被阻止。仅当客户端断开连接时,服务器才会使用断开的管道输出消息和panic

1 个答案:

答案 0 :(得分:4)

  

我发送了一些数据并以 ^ D 结尾,它应该是EOF

nc的输入。这并不意味着套接字本身是关闭的:

  

当netcat的标准输入端遇到EOF时,它可能会或可能会   不关闭其TCP连接的发送部分,具体取决于哪个   是netcat的版本。

     
  

ctrl + d在netcat的stdin上发送EOF :netcat注意到EOF。它不会通过套接字发送更多数据。但是,   继续运行并从套接字读取数据,以防服务器有   还有更多数据要发送。

     

对于它的价值,我无法使用系统提供的nc在macOS 10.14.1上重现您的问题。

对于您的-q版本,您可以使用-wnc选项:

  

假设发送EOF连接后将保持空闲状态,则可以使用-w timeout选项,该选项适用于timeout等于零

     

您也可以尝试不互动:

$ echo 'hello' | nc -U socket
hello

另请参阅: