Обмен строками по TCP в Rust
После установления связи стороны обмениваются байтами в обе стороны. Клиент обычно шлет запрос, сервер читает порцию в буфер, интерпретирует текст и пишет ответ обратно в тот же поток.
На стороне сервера прочитаем данные в массив и проверим, что байты составляют корректный текст UTF-8:
use std::io::{Read, Write};
use std::net::TcpListener;
fn main() {
let listener = match TcpListener::bind("127.0.0.1:7000") {
Ok(l) => l,
Err(e) => {
eprintln!("bind error: {}", e);
return;
}
};
let (mut stream, _peer) = match listener.accept() {
Ok(pair) => pair,
Err(e) => {
eprintln!("accept error: {}", e);
return;
}
};
let mut buf = [0u8; 64];
let n = match stream.read(&mut buf) {
Ok(count) => count,
Err(e) => {
eprintln!("read error: {}", e);
return;
}
};
match std::str::from_utf8(&buf[..n]) {
Ok(text) => println!("got {}", text),
Err(_) => println!("bad utf8"),
}
match stream.write_all(b"reply") {
Ok(()) => println!("sent reply"),
Err(e) => eprintln!("write error: {}", e),
}
}
Чтение может вернуть меньше байт, чем вместит буфер: для короткого сообщения достаточно среза до числа прочитанных байт. Преобразование в строку через сопоставление отделяет битый текст от удачного декодирования.
Клиент отправляет строку и ждет ответ тем же способом:
use std::io::{Read, Write};
use std::net::TcpStream;
fn main() {
let mut stream = match TcpStream::connect("127.0.0.1:7000") {
Ok(s) => s,
Err(e) => {
eprintln!("connect error: {}", e);
return;
}
};
match stream.write_all(b"question") {
Ok(()) => {}
Err(e) => {
eprintln!("write error: {}", e);
return;
}
}
let mut buf = [0u8; 64];
let n = match stream.read(&mut buf) {
Ok(count) => count,
Err(e) => {
eprintln!("read error: {}", e);
return;
}
};
match std::str::from_utf8(&buf[..n]) {
Ok(text) => println!("answer {}", text),
Err(_) => println!("bad utf8"),
}
}
Дан адрес:
let addr = "127.0.0.1:7000";
На сервере примите одного гостя,
прочитайте буфер, выведите текст
ask при успешном декодировании
и отправьте ответ yes.
Дан адрес:
let addr = "127.0.0.1:7000";
На клиенте отправьте ask,
прочитайте ответ в буфер и напечатайте
его как строку через сопоставление.
Скажите, почему для текста используют срез буфера по числу прочитанных байт, а не весь массив целиком.