Сервер сокетов домена Unix печатает сообщение только при закрытии клиента [дубликат]
Я пытаюсь реализовать сервер сокетов домена Unix в Rust, который позволяет клиенту подключаться, затем клиент отправляет сообщение через сокет, а сервер его печатает. Однако сервер не печатает сообщение, пока я не закрою (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, но он просто не печатает, пока клиент не закроется. Кто-нибудь знает, в чем проблема?
Ответы
bf.read_line(&mut out);
Ваш прочитанный код читает строки . Но ваш код отправки не отправляет строку. Таким образом, код чтения продолжает пытаться прочитать строку, как вы его просили. Когда соединение закрывается, прочитанный код больше не может пытаться прочитать строку, поэтому он возвращается.
Вы должны реализовать один и тот же протокол с обеих сторон. Если читатель понимает, что концы строк являются границами сообщения, то писатель должен поместить строку, заканчивающуюся в каждой точке, в которой принимающий код понимает, что сообщение заканчивается.
Кстати, действительно неплохо задокументировать любой протокол, который вы собираетесь наложить поверх сетевого протокола, по крайней мере, пока вы не наберетесь опыта. Это позволило бы избежать такой ошибки. Либо протокол скажет, что сообщения состоят из строк, либо он скажет, что они состоят из чего-то еще, и это даст понять, какая сторона неправильная, а какая правильная.
В настоящее время ни одна из сторон не права и права. Они просто не согласны. Этих ошибок можно полностью избежать благодаря надлежащей документации протокола. Является ли протокол, который эти две программы используют для связи друг с другом, линейным? Или нет? Чтобы знать, вам нужна документация. Это стоит усилий, чтобы задокументировать.