Unix 도메인 소켓 서버는 클라이언트가 닫힐 때만 메시지를 인쇄합니다. [중복]

Dec 04 2020

Rust에서 Unix Domain Socket Server를 구현하려고하는데, 클라이언트가 연결하면 클라이언트가 소켓을 통해 메시지를 보내고 서버가이를 인쇄합니다. 그러나 서버는 클라이언트 프로세스를 닫을 때까지 (CTLR + C) 메시지를 인쇄하지 않습니다. 문제가 무엇일까요? 다음은 두 가지 코드입니다.

섬기는 사람:

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

fn main() {
    let listener = UnixListener::bind("/tmp/socket.sock").unwrap();

    for stream in listener.incoming() {
        match stream {
            Ok(mut stream) => {
                println!("Client connected!");
                thread::spawn(move ||  {
                    let mut out = String::new();
                    let mut bf = BufReader::new(stream);
                    bf.read_line(&mut out);
                    println!("{}", out);
                });
            } Err(err) => {
                println!("Connection failed!");
                break;
            }
        }
    }
    println!("Hello, world!");
}

고객:

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

fn main() {
    let mut stream = UnixStream::connect("/tmp/socket.sock").unwrap();
    let mut bf = BufWriter::new(&stream);

    bf.write_all("Hello server".as_bytes());
    bf.flush();
    drop(bf);
}

read_to_string 메서드로도 시도했지만 클라이언트가 닫힐 때까지 인쇄되지 않습니다. 문제가 무엇인지 아는 사람이 있습니까?

답변

1 DavidSchwartz Dec 04 2020 at 18:06
bf.read_line(&mut out);

읽기 코드는 줄을 읽습니다 . 그러나 보내는 코드는 한 줄을 보내지 않습니다. 따라서 읽기 코드는 사용자가 요청한대로 계속해서 행을 읽으려고합니다. 연결이 닫히면 읽기 코드는 더 이상 줄을 읽으려고 할 수 없으므로 반환됩니다.

양쪽에서 동일한 프로토콜을 구현해야합니다. 독자가 줄 끝이 메시지 경계라는 것을 이해하는 경우 작성자는 수신 코드가 메시지를 이해하기를 원하는 각 지점에 줄 끝을 배치해야합니다.

그건 그렇고, 적어도 훨씬 더 많은 경험을 얻을 때까지 네트워크 프로토콜 위에 계층화 할 프로토콜을 문서화하는 것은 정말 좋은 생각입니다. 그것은 이런 종류의 실수를 피했을 것입니다. 프로토콜은 메시지가 줄로 구성되어 있거나 다른 것으로 구성되어 있다고 말하면 어느 쪽이 틀렸고 어느 쪽이 옳은지를 분명히 할 수 있습니다.

지금처럼 어느 쪽도 틀리거나 옳지 않습니다. 그들은 동의하지 않습니다. 이러한 실수는 적절한 프로토콜 문서로 완전히 방지됩니다. 이 두 프로그램이 서로 통신하는 데 사용하는 프로토콜이 회선 기반입니까? 아니면? 알아야 할 문서가 필요합니다. 문서화하는 노력의 가치가 있습니다.