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地址");
            
            // 可以添加失败后的重试逻辑或退出程序
        }
    }
}

特性

  1. 轻量级实现
  2. 异步支持
  3. 简单易用的API

使用注意事项

  1. 需要tokio运行时环境
  2. 需要网络连接才能获取公网IP
  3. 如果设备处于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(&current_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;
        }
    }
}

这个完整示例包含了以下功能:

  1. 基本IPv4地址查询
  2. 基本IPv6地址查询
  3. 同时查询IPv4和IPv6地址
  4. 自定义查询超时设置
  5. 使用自定义IP查询服务
  6. 详细的错误处理
  7. IP地址变化监控(简化版,实际应用中可以长期运行)

要运行这个示例,需要在Cargo.toml中添加以下依赖:

[dependencies]
public-ip = "0.2"
tokio = { version = "1", features = ["full"] }
回到顶部