O servidor de soquete de domínio Unix só imprime mensagem quando o cliente fecha [duplicado]
Estou tentando implementar um servidor de soquete de domínio Unix em Rust, que permite que um cliente se conecte, então o cliente envia uma mensagem pelo soquete e o servidor a imprime. No entanto, o servidor não imprime a mensagem até que eu feche (CTLR + C) o processo do cliente. Qual poderia ser o problema? Aqui estão os dois códigos:
Servidor:
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!");
}
Cliente:
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);
}
Também tentei com o método read_to_string, mas ele simplesmente não imprime até que o cliente feche. Alguém tem ideia de qual é o problema?
Respostas
bf.read_line(&mut out);
Seu código lido lê as linhas . Mas o seu código de envio não envia uma linha. Portanto, o código de leitura continua tentando ler uma linha conforme você pediu. Quando a conexão é fechada, o código lido não pode mais tentar ler uma linha, então ele retorna.
Você deve implementar o mesmo protocolo em ambos os lados. Se o leitor entender que terminações de linha são limites de mensagem, então o escritor deve colocar uma linha terminando em cada ponto em que você deseja que o código de recebimento entenda o final de uma mensagem.
A propósito, é realmente uma boa ideia documentar qualquer protocolo que você vai sobrepor a um protocolo de rede, pelo menos até ter muito mais experiência. Isso teria evitado esse tipo de erro. O protocolo diria que as mensagens consistem em linhas ou diria que consistem em outra coisa, e isso deixaria claro qual lado está errado e qual está certo.
Como está agora, nenhum dos lados está certo ou errado. Eles simplesmente discordam. Esses erros são completamente evitados pela documentação de protocolo adequada. O protocolo que esses dois programas estão usando para se comunicarem é baseado em linha? Ou não? Você precisa de documentação para saber. Vale o esforço para documentar.