首页 > 解决方案 > Unix Domain Socket Server 仅在客户端关闭时打印消息

问题描述

我正在尝试在 Rust 中实现一个 Unix 域套接字服务器,它允许客户端连接,然后客户端通过套接字发送消息,服务器打印它。但是,在我关闭(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 方法,但它只是在客户端关闭之前不会打印。有谁知道问题是什么?

标签: socketsunixrust

解决方案


bf.read_line(&mut out);

您的读取代码读取。但是您的发送代码不会发送一行。因此,读取的代码继续尝试按照您的要求读取一行。当连接关闭时,读取的代码不能再尝试读取一行,所以它返回。

您必须在双方都实现相同的协议。如果读者将行结尾理解为消息边界,那么编写者必须在您希望接收代码理解消息结束的每个点处放置一个行结尾。

顺便说一句,记录您要在网络协议之上分层的任何协议确实是一个好主意,至少在您获得更多经验之前是这样。这样就可以避免这种错误。协议要么会说消息由行组成,要么会说它们由其他内容组成,这将明确哪一方是错误的,哪一方是正确的。

像现在这样,任何一方都没有对错。他们只是不同意。适当的协议文档可以完全避免这些错误。这两个程序用于相互通信的协议是基于线路的吗?或不?你需要文件才能知道。值得努力记录。


推荐阅读