std::net::IpAddr
传入。对于动态解析,我想使用域名。
Rust 似乎确实提供了一种将域名解析为 IP 的方法,但它需要一个端口:
to_socket_addrs
on str
use std::net::{ToSocketAddrs};
fn main() {
let socket_str = "localhost:12345";
let mut addrs_iter = socket_str.to_socket_addrs().unwrap();
let addr = addrs_iter.next().unwrap();
dbg!(addr.ip()); // resolved IP
}
因为我正在执行 ICMP 请求,所以不需要端口。
我还没有找到一种方法来在标准库中仅对域名(而不是端口)进行解析。 有这样的功能吗?
我会以这种方式模仿类似
gethostbyname()
的东西。
如果我们在解析期间不需要特定端口,我们只需使用端口
0
。
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs};
fn gethostbyname(
hostname: &str
) -> Result<IpAddr, Box<dyn std::error::Error>> {
if let Ok(mut sock_addrs) = format!("{}:0", hostname).to_socket_addrs() {
if let Some(sock_addr) = sock_addrs.next() {
return Ok(sock_addr.ip());
}
}
Err(format!("no ip address for {:?}", hostname))?
}
fn gethostbyname_v4(
hostname: &str
) -> Result<Ipv4Addr, Box<dyn std::error::Error>> {
if let Ok(sock_addrs) = format!("{}:0", hostname).to_socket_addrs() {
for sock_addr in sock_addrs {
if let SocketAddr::V4(sock_addr) = sock_addr {
return Ok(sock_addr.ip().clone());
}
}
}
Err(format!("no ipv4 address for {:?}", hostname))?
}
fn gethostbyname_v6(
hostname: &str
) -> Result<Ipv6Addr, Box<dyn std::error::Error>> {
if let Ok(sock_addrs) = format!("{}:0", hostname).to_socket_addrs() {
for sock_addr in sock_addrs {
if let SocketAddr::V6(sock_addr) = sock_addr {
return Ok(sock_addr.ip().clone());
}
}
}
Err(format!("no ipv6 address for {:?}", hostname))?
}
fn main() {
for host in [
"localhost",
"www.rust-lang.org",
"does.not.exist",
"192.168.25.137",
] {
println!("• {:?}", host);
println!(" ip {:?}", gethostbyname(host));
println!(" ipv4 {:?}", gethostbyname_v4(host));
println!(" ipv6 {:?}", gethostbyname_v6(host));
}
}
/*
• "localhost"
ip Ok(::1)
ipv4 Ok(127.0.0.1)
ipv6 Ok(::1)
• "www.rust-lang.org"
ip Ok(3.165.136.16)
ipv4 Ok(3.165.136.16)
ipv6 Ok(2600:9000:2729:2a00:14:513f:eb40:93a1)
• "does.not.exist"
ip Err("no ip address for \"does.not.exist\"")
ipv4 Err("no ipv4 address for \"does.not.exist\"")
ipv6 Err("no ipv6 address for \"does.not.exist\"")
• "192.168.25.137"
ip Ok(192.168.25.137)
ipv4 Ok(192.168.25.137)
ipv6 Err("no ipv6 address for \"192.168.25.137\"")
*/