rpc_api_server/
find_port.rs1use 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}