rpc_api_server/
find_port.rs

1use std::borrow::BorrowMut;
2use std::io::repeat;
3use std::net::TcpListener;
4use std::ops::Range;
5use std::sync::atomic::{AtomicU16, Ordering};
6
7static last_port: AtomicU16 = AtomicU16::new(10000);
8
9
10pub fn find_port() -> Option<u16> {
11    loop {
12        let port = last_port.fetch_add(1, Ordering::SeqCst);
13        if port_is_available(port) { return Some(port); }
14        if port > 20000 { return None; }
15    }
16}
17
18pub fn find_port_in(range: Range<u16>) -> Option<u16> {
19    let mut range1 = range.clone();
20    range1.find(|port| port_is_available(*port))
21}
22
23fn port_is_available(port: u16) -> bool {
24    match TcpListener::bind(("0.0.0.0", port)) {
25        Ok(_) => true,
26        Err(_) => false,
27    }
28}
29
30#[cfg(test)]
31mod test {
32    use crate::find_port::find_port;
33
34    #[test]
35    fn test_no_reuse() {
36        let p1 = find_port().unwrap();
37        let p2 = find_port().unwrap();
38        assert_ne!(p1, p2)
39    }
40}