Description
The docs currently have this example on the page for TcpListener:
https://doc.rust-lang.org/std/net/struct.TcpListener.html
use std::net::{TcpListener, TcpStream};
use std::thread;
let listener = TcpListener::bind("127.0.0.1:80").unwrap();
fn handle_client(stream: TcpStream) {
// ...
}
// accept connections and process them, spawning a new thread for each one
for stream in listener.incoming() {
match stream {
Ok(stream) => {
thread::spawn(move|| {
// connection succeeded
handle_client(stream)
});
}
Err(e) => { /* connection failed */ }
}
}
// close the socket server
drop(listener);
The problem is, this cannot be exited in a clean way. I stumbled upon this by trying to play around with this and threads, my setup right now is a thread opening the socket, and another continually accepting streams and sending them to another thread. This works until shutdown. I cannot stop the iterator in a clean way. I could kill the thread, but I might leak open filedescriptors that way, which is obviously not clean.
An option would be having an iterator that blocks with a timeout. But as of today there is no way to set an timeout from outside.
In src/libstd/sys/unix/net.rs
is a set_timeout
method, but it is not used for the TcpListener as far as I can tell. (A quick ag set_timeout
only returned results for a TcpStream.)
The example is misleading that it implies that it closes the Socket Server, which, as of today, it does not. It also means that you can only exit when killing the thread/program, which implies that no Destructors are run.
Are there any solutions? Am I doing something wrong?