Почему отправка ^ D с netcat не вызывает EOF при чтении из сокета Unix? - PullRequest
0 голосов
/ 05 декабря 2018

Я пытаюсь написать сервер, который будет читать из сокета 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
    }
}

( детская площадка )

На стороне клиента я использую nc: nc -U socket.Я посылаю некоторые данные и заканчиваю их ^ D , которая должна быть EOF.Документы для read_to_string говорят:

Считать все байты до EOF в этом источнике, добавив их в buf

Ожидаемое поведение: После отправки ^ D на стороне клиента сервер отвечает echo

Наблюдаемое поведение: сервер не распознает, что EOF был отправлен, и блокируется.Только когда клиент разрывает соединение, сервер печатает сообщение и panic s с разорванным конвейером.

1 Ответ

0 голосов
/ 05 декабря 2018

Я отправляю некоторые данные и заканчиваю их ^ D , что должно быть EOF

То есть, на вход nc.Это не означает, что сам сокет закрыт:

Когда netcat сталкивается с EOF на своем стандартном входе, он может закрывать или не закрывать отправляющую часть своего соединения TCP, в зависимости от того, какойверсия netcat:

ctrl + d, который отправляет EOF на стандартный вывод netcat : netcat заметил EOF.Он не будет отправлять дальнейшие данные через сокет.Тем не менее, он продолжает работать и читать из сокета, если на сервере есть больше данных для отправки.

Я не могу воспроизвести вашу проблему на macOS 10.14.1 с поставляемой системой nc.

. Возможно, вы сможете использовать -q или -w опции для вашей версии nc:

Предполагая, что после отправки EOF соединение останется свободным, вы можете использовать опцию -w timeout, которая работает для timeout, равнойноль

Вы также можете попробовать не быть интерактивным:

$ echo 'hello' | nc -U socket
hello

См. Также:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...