Ответ 1
Вот очень простой пример, используя std::net
. Он был разработан против нынешнего мастера Руста и должен работать и на 1. *.
Будьте осторожны с этим примером; он упрощен; вы можете не захотеть, чтобы он впал в панику, если ошибка связи, прослушивания или принятия вызвала ошибку.
use std::io::Write;
use std::net::TcpListener;
use std::thread;
fn main() {
let listener = TcpListener::bind("127.0.0.1:9123").unwrap();
println!("listening started, ready to accept");
for stream in listener.incoming() {
thread::spawn(|| {
let mut stream = stream.unwrap();
stream.write(b"Hello World\r\n").unwrap();
});
}
}
Обратите внимание на парадигму в отношении принятия; вы должны инициировать запрос accept()
самостоятельно (в этом примере мы используем итератор incoming()
, который просто вызывает accept()
каждый раз), и поэтому вы получаете реальный контроль над тем, какие задачи существуют.
В результате я поместил фактический код обработки потока в отдельный поток, но это не обязательно для очень коротких запросов (это просто означает, что вы не сможете обрабатывать второй запрос при обработке первого ); вы можете просто удалить thread::spawn(|| { ... })
об этих двух строках. Использование дополнительных потоков также дает определенную степень изоляции; если поток отключится, сервер в целом не умрет (помните, однако, что нехватка памяти или паника деструктора во время размотки приведет к смерти всего сервера).