Unix Domain Socket Server drukuje komunikat tylko wtedy, gdy klient zamyka się [duplikat]
Próbuję zaimplementować Unix Domain Socket Server w Rust, który umożliwia klientowi połączenie, a następnie wysyła wiadomość przez gniazdo, a serwer ją drukuje. Jednak serwer nie drukuje wiadomości, dopóki nie zamknę (CTLR + C) procesu klienta. Jaki może być problem? Oto oba kody:
Serwer:
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!");
}
Klient:
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);
}
Wypróbowałem to również z metodą read_to_string, ale po prostu nie drukuje, dopóki klient nie zamknie. Czy ktoś ma pojęcie w czym jest problem?
Odpowiedzi
bf.read_line(&mut out);
Twój odczytany kod czyta linie . Ale twój kod wysyłający nie wysyła linii. Tak więc kod odczytu kontynuuje próbę odczytania wiersza, tak jak go prosiłeś. Gdy połączenie jest zamknięte, odczytany kod nie może już próbować odczytać wiersza, więc zwraca.
Musisz wdrożyć ten sam protokół po obu stronach. Jeśli czytelnik rozumie, że końce wierszy są granicami wiadomości, wówczas autor musi umieścić koniec wiersza w każdym punkcie, w którym kod odbierający ma rozumieć zakończenie komunikatu.
Nawiasem mówiąc, naprawdę dobrym pomysłem jest udokumentowanie każdego protokołu, który zamierzasz nakładać na protokół sieciowy, przynajmniej do czasu, gdy będziesz bardziej doświadczony. To pozwoliłoby uniknąć tego rodzaju pomyłki. Albo protokół powiedziałby, że wiadomości składają się z linii, albo powiedziałby, że składają się z czegoś innego, co dałoby jasno do zrozumienia, która strona jest zła, a która jest właściwa.
Tak jak jest teraz, żadna ze stron nie jest zła ani dobra. Po prostu się nie zgadzają. Tych błędów całkowicie unika odpowiednia dokumentacja protokołu. Czy protokół, którego te dwa programy używają do komunikacji liniowej? Albo nie? Potrzebujesz dokumentacji, aby wiedzieć. Warto to udokumentować.