Rust网络工具库public-ip的使用:快速获取公网IP地址的轻量级解决方案
Rust网络工具库public-ip的使用:快速获取公网IP地址的轻量级解决方案
简介
rust-public-ip是一个轻量级的Rust库,用于快速获取设备的公网IP地址。
安装
在Cargo.toml中添加以下依赖:
public-ip = "0.2"
或者运行以下命令:
cargo add public-ip
示例用法
基础示例代码如下:
#[tokio::main]
async fn main() {
// 尝试获取IP地址并打印
if let Some(ip) = public_ip::addr().await {
println!("public ip address: {:?}", ip);
} else {
println!("couldn't get an IP address");
}
}
完整示例代码
以下是更完整的示例,包含错误处理和日志记录:
use log::{info, error};
#[tokio::main]
async fn main() {
// 初始化日志系统
env_logger::init();
// 异步获取公网IP地址
match public_ip::addr().await {
Some(ip) => {
// 成功获取IP地址
info!("成功获取公网IP地址: {}", ip);
// 可以在这里添加对IP地址的后续处理
// 例如:存储到文件、发送到远程服务器等
},
None => {
// 获取IP地址失败时的处理
error!("无法获取公网IP地址");
// 可以添加失败后的重试逻辑或退出程序
}
}
}
特性
- 轻量级实现
- 异步支持
- 简单易用的API
使用注意事项
- 需要tokio运行时环境
- 需要网络连接才能获取公网IP
- 如果设备处于NAT后面,获取的将是网关的公网IP
依赖说明
完整示例需要添加以下依赖到Cargo.toml:
[dependencies]
public-ip = "0.2"
tokio = { version = "1.0", features = ["full"] }
log = "0.4"
env_logger = "0.9"
许可证
该项目使用MIT许可证。
1 回复
下面是根据你提供的内容整理的完整示例demo,包含注释说明:
// 引入必要的模块
use public_ip::{get_ipv4, get_ipv6, get_both, AddressFamily, Error, Service};
use std::time::Duration;
use tokio::time;
// 主函数使用tokio异步运行时
#[tokio::main]
async fn main() {
// 示例1: 基本IPv4查询
println!("--- 基本IPv4查询示例 ---");
match get_ipv4().await {
Ok(ip) => println!("您的公网IPv4地址是: {}", ip),
Err(e) => eprintln!("获取IPv4地址失败: {}", e),
}
// 示例2: 基本IPv6查询
println!("\n--- 基本IPv6查询示例 ---");
match get_ipv6().await {
Ok(ip) => println!("您的公网IPv6地址是: {}", ip),
Err(e) => eprintln!("获取IPv6地址失败: {}", e),
}
// 示例3: 同时查询IPv4和IPv6
println!("\n--- 同时查询IPv4和IPv6示例 ---");
match get_both().await {
Ok((ipv4, ipv6)) => {
println!("您的公网IPv4地址是: {}", ipv4);
if let Some(ipv6) = ipv6 {
println!("您的公网IPv6地址是: {}", ipv6);
}
}
Err(e) => eprintln!("获取IP地址失败: {}", e),
}
// 示例4: 自定义超时设置
println!("\n--- 自定义超时设置示例 ---");
let timeout = Duration::from_secs(3); // 3秒超时
match get_ipv4().timeout(timeout).await {
Ok(Ok(ip)) => println!("您的公网IPv4地址是: {}", ip),
Ok(Err(e)) => eprintln!("获取IPv4地址失败: {}", e),
Err(_) => eprintln!("请求超时"),
}
// 示例5: 使用自定义服务列表
println!("\n--- 自定义服务列表示例 ---");
let custom_services = vec![
Service::new("https://api.ipify.org", AddressFamily::IPv4),
Service::new("https://ident.me", AddressFamily::IPv4),
];
match get_ipv4().services(custom_services).await {
Ok(ip) => println!("您的公网IPv4地址是: {}", ip),
Err(e) => eprintln!("获取IPv4地址失败: {}", e),
}
// 示例6: 详细的错误处理
println!("\n--- 详细错误处理示例 ---");
match get_ipv4().await {
Ok(ip) => println!("您的公网IPv4地址是: {}", ip),
Err(Error::Timeout) => eprintln!("请求超时"),
Err(Error::NoService) => eprintln!("没有可用的服务"),
Err(Error::InvalidResponse) => eprintln!("服务返回无效响应"),
Err(Error::RequestFailed(e)) => eprintln!("请求失败: {}", e),
}
// 示例7: IP变化监控(运行5分钟后退出)
println!("\n--- IP变化监控示例(运行5分钟) ---");
let mut last_ip = None;
let mut interval = time::interval(Duration::from_secs(60)); // 每分钟检查一次
let mut count = 0;
const MAX_COUNT: i32 = 5; // 运行5次后退出
loop {
interval.tick().await;
count += 1;
match get_ipv4().await {
Ok(current_ip) => {
if last_ip.as_ref() != Some(¤t_ip) {
println!("IP地址从 {:?} 变更为 {}", last_ip, current_ip);
last_ip = Some(current_ip);
} else {
println!("IP地址未变化,仍然是 {}", current_ip);
}
}
Err(e) => eprintln!("检查IP时出错: {}", e),
}
if count >= MAX_COUNT {
println!("监控结束");
break;
}
}
}
这个完整示例包含了以下功能:
- 基本IPv4地址查询
- 基本IPv6地址查询
- 同时查询IPv4和IPv6地址
- 自定义查询超时设置
- 使用自定义IP查询服务
- 详细的错误处理
- IP地址变化监控(简化版,实际应用中可以长期运行)
要运行这个示例,需要在Cargo.toml中添加以下依赖:
[dependencies]
public-ip = "0.2"
tokio = { version = "1", features = ["full"] }