Broadcast
- Rust course
- Advanced
- Lesson 28/81
- 6 min
Write to all clients through a Vec<TcpStream>.
Broadcast
When a message arrives, it must be forwarded to everyone except the sender. Separating the broadcast logic from the network makes testing easy: let the function write to any list of Writes. On the real server the list is made of TcpStreams, in a test of Vec<u8> buffers:
fn yayinla<W: Write>(istemciler: &mut [W], gonderen: usize, mesaj: &str) {
for (i, w) in istemciler.iter_mut().enumerate() {
if i != gonderen {
let _ = writeln!(w, "{mesaj}"); // a dropped client shouldn't stop everyone
}
}
}In-memory testing
Since Vec<u8> implements Write, we can try the broadcast without a network:
let mut tamponlar: Vec<Vec<u8>> = vec![Vec::new(); 3];
yayinla(&mut tamponlar, 0, "ece: selam");
for (i, t) in tamponlar.iter().enumerate() {
let metin = String::from_utf8_lossy(t);
println!("{i}: {}", if metin.is_empty() { "-" } else { metin.trim() });
}This is a small example of separating business logic from I/O (a sans-IO design).
Practice Broadcast
Write the generic yayinla function above. Broadcast the message ece: selam from sender 0 to three Vec<u8> buffers and print each buffer as i: content (- if empty).
Starter code
use std::io::Write;
fn main() {
// buraya yaz
}Sample solution
use std::io::Write;
fn yayinla<W: Write>(istemciler: &mut [W], gonderen: usize, mesaj: &str) {
for (i, w) in istemciler.iter_mut().enumerate() {
if i != gonderen {
let _ = writeln!(w, "{mesaj}");
}
}
}
fn main() {
let mut tamponlar: Vec<Vec<u8>> = vec![Vec::new(); 3];
yayinla(&mut tamponlar, 0, "ece: selam");
for (i, t) in tamponlar.iter().enumerate() {
let metin = String::from_utf8_lossy(t);
println!("{}: {}", i, if metin.is_empty() { "-" } else { metin.trim() });
}
}Expected output
0: - 1: ece: selam 2: ece: selam
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Why ignore the write error instead of propagating it with <code>?</code>?
- The compiler forces it
- It prevents others from missing the message because of one disconnected client Correct answer
- Errors don't matter
- Write returns no errors
Explanation: On a real server, clients failing to write are marked for removal from the list.
2 Except the sender
for (i, w) in istemciler.iter_mut().enumerate() {
if i ____ gonderen {
let _ = writeln!(w, "{mesaj}");
}
}
for (i, w) in istemciler.iter_mut().enumerate() {
if i != gonderen {
let _ = writeln!(w, "{mesaj}");
}
}
Explanation: The message is written to everyone except the sender.
3 Client and what it receives (sender 0)
| Term | Meaning |
|---|---|
0 |
- |
1 |
ece: selam |
writeln! error |
Ignored |
Vec<u8> |
Implements Write |