I have a TCP server listening on requests in an infinite loop:
use std::io::prelude::*;
use std::net::TcpStream;
use std::net::TcpListener;
fn main() {
let listener = TcpListener::bind("0.0.0.0:7878").unwrap();
for stream in listener.incoming() {
let mut stream = stream.unwrap();
let response = "HTTP/1.1 200 OK\r\n\r\nsdfuhgsjdfghsdfjk";
stream.write(response.as_bytes()).unwrap();
stream.flush().unwrap();
}
}
How can I break the loop after a period of time (timeout) ?
After the timeout elapsed, I need the listening loop to stop:
There are three possible solutions to cancel the blocking listener.incoming() call detailed in the Stack Overflow question "Graceful exit TcpListener.incoming()":
listener.set_nonblocking(true)
), and checking if the timeout has expired when the iterator returns an io::ErrorKind::WouldBlock
error.let fd = listener.as_raw_fd();
before the loop, and then call libc::shutdown(fd, libc::SHUT_RD);
to cause the incoming
iterator to return an error.I also found the cancellable_io
crate that replaces TcpListener and implements cancelation.
IMHO it is unfortunate that the Rust std::net doesn't include a method to cancel the listener.
Perhaps this question should be marked as a duplicate of the mentioned Stack Overflow question, but I don't have the reputation to do so.