Unix Domain Socket Server n’imprime le message que lorsque le client se ferme [dupliquer]
J'essaie d'implémenter un serveur de socket de domaine Unix dans Rust, qui permet à un client de se connecter, puis le client envoie un message via le socket et le serveur l'imprime. Cependant, le serveur n'imprime pas le message tant que je n'ai pas fermé (CTLR + C) le processus client. Quel pourrait être le problème? Voici les deux codes:
Serveur:
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!");
}
Client:
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);
}
Je l'ai essayé avec la méthode read_to_string aussi, mais il ne s'imprime tout simplement pas tant que le client ne se ferme pas. Quelqu'un a-t-il une idée de ce qu'est le problème?
Réponses
bf.read_line(&mut out);
Votre code de lecture lit des lignes . Mais votre code d'envoi n'envoie pas de ligne. Ainsi, le code de lecture continue d'essayer de lire une ligne comme vous l'avez demandé. Lorsque la connexion est fermée, le code de lecture ne peut plus essayer de lire une ligne, il revient donc.
Vous devez mettre en œuvre le même protocole des deux côtés. Si le lecteur comprend que les fins de ligne sont des limites de message, le rédacteur doit placer une ligne se terminant à chaque point où vous souhaitez que le code de réception comprenne la fin d'un message.
Au fait, c'est vraiment une bonne idée de documenter tout protocole que vous allez superposer à un protocole réseau, au moins jusqu'à ce que vous soyez beaucoup plus expérimenté. Cela aurait évité ce genre d'erreur. Soit le protocole dirait que les messages se composent de lignes, soit il dirait qu'ils consistent en quelque chose d'autre, ce qui indiquerait clairement quel côté a tort et lequel est juste.
Dans l'état actuel des choses, aucun des deux camps n'a tort ou raison. Ils ne sont tout simplement pas d'accord. Ces erreurs sont complètement évitées par une documentation appropriée du protocole. Le protocole que ces deux programmes utilisent pour communiquer entre eux est-il basé sur une ligne? Ou pas? Vous avez besoin de documentation pour savoir. Cela vaut la peine de documenter.