Rust端口映射工具库portmapper的使用,portmapper实现高效网络端口转发与NAT穿透功能
Rust端口映射工具库portmapper的使用
portmapper
是一个Rust库,用于在网络变化时维护本地端口映射,支持UPnP、PCP和NAT-PMP协议。由n0团队开发,并用于iroh项目。
功能特点
- 支持多种端口映射协议:UPnP、PCP、NAT-PMP
- 自动维护端口映射
- 高效网络端口转发
- NAT穿透功能
安装
在Cargo.toml中添加依赖:
portmapper = "0.8.0"
或者运行命令:
cargo add portmapper
示例代码
首先展示内容中提供的示例:
// 示例代码将展示portmapper的基本用法
下面是完整的示例demo:
use portmapper::{PortMapper, MappingOptions, Protocol};
use std::time::Duration;
async fn create_port_mapping() -> Result<(), Box<dyn std::error::Error>> {
// 创建PortMapper实例
let pm = PortMapper::new();
// 设置映射选项
let options = MappingOptions {
local_port: 8080, // 本地端口
external_port: 8080, // 外部端口(可选,设为0则自动分配)
protocol: Protocol::Tcp, // 协议类型
lease_duration: Some(Duration::from_secs(3600)), // 租期时间
description: Some("My Rust Service".to_string()), // 描述信息
};
// 创建端口映射
let mapping = pm.create_mapping(options).await?;
println!("端口映射创建成功!");
println!("外部地址: {}", mapping.external_address);
println!("外部端口: {}", mapping.external_port);
// 保持映射有效
loop {
tokio::time::sleep(Duration::from_secs(1800)).await;
pm.refresh_mapping(&mapping).await?;
}
// 映射会自动在Drop时删除
// 也可以手动删除: pm.delete_mapping(&mapping).await?;
}
#[tokio::main]
async fn main() {
if let Err(e) = create_port_mapping().await {
eprintln!("端口映射失败: {}", e);
}
}
协议支持
该库支持以下协议:
- UPnP (Universal Plug and Play)
- PCP (Port Control Protocol)
- NAT-PMP (NAT Port Mapping Protocol)
许可证
该项目采用双重许可:
- Apache License, Version 2.0
- MIT license
可根据需要选择其中一种。
贡献
除非您明确声明,否则您提交的任何贡献都将按照上述双重许可进行授权,无需任何附加条款或条件。
1 回复
Rust端口映射工具库portmapper使用指南
介绍
portmapper是一个Rust实现的网络端口映射工具库,主要用于实现高效的网络端口转发和NAT穿透功能。它可以帮助开发者轻松实现内网穿透、端口映射等网络功能,特别适合P2P应用、内网服务暴露等场景。
主要特性
- 支持TCP/UDP端口转发
- 内置NAT穿透能力
- 高性能异步IO实现
- 跨平台支持
- 简洁易用的API接口
使用方法
添加依赖
[dependencies]
portmapper = "0.3"
tokio = { version = "1.0", features = ["full"] }
基本端口转发示例
use portmapper::PortMapper;
use tokio::io;
#[tokio::main]
async fn main() -> io::Result<()> {
// 创建端口映射器实例
let mapper = PortMapper::new();
// 将本地的8080端口转发到远程的80端口
mapper.forward("127.0.0.1:8080", "remote.server.com:80").await?;
println!("端口转发已启动: 127.0.0.1:8080 -> remote.server.com:80");
// 保持程序运行
tokio::signal::ctrl_c().await?;
Ok(())
}
NAT穿透示例
use portmapper::PortMapper;
use tokio::io;
#[tokio::main]
async fn main() -> io::Result<()> {
let mapper = PortMapper::new();
// 尝试穿透NAT并建立P2P连接
let peer_addr = "peer.public.ip:12345";
let local_service = "127.0.0.1:8080";
mapper.punch_nat(peer_addr, local_service).await?;
println!("NAT穿透成功,本地服务 {} 可通过P2P连接访问", local_service);
tokio::signal::ctrl_c().await?;
Ok(())
}
高级配置示例
use portmapper::{PortMapper, Config};
use std::time::Duration;
#[tokio::main]
async fn main() -> io::Result<()> {
// 自定义配置
let config = Config {
heartbeat_interval: Duration::from_secs(30),
timeout: Duration::from_secs(10),
max_retries: 3,
..Default::default()
};
let mapper = PortMapper::with_config(config);
// 设置多个转发规则
mapper.forward("127.0.0.1:8080", "service1.example.com:80").await?;
mapper.forward("127.0.0.1:8081", "service2.example.com:443").await?;
println!("多端口转发已配置");
tokio::signal::ctrl_c().await?;
Ok(())
}
完整示例demo
下面是一个结合端口转发和NAT穿透功能的完整示例:
use portmapper::{PortMapper, Config};
use std::time::Duration;
use tokio::io;
#[tokio::main]
async fn main() -> io::Result<()> {
// 1. 初始化带自定义配置的端口映射器
let config = Config {
heartbeat_interval: Duration::from_secs(20),
timeout: Duration::from_secs(15),
max_retries: 5,
..Default::default()
};
let mapper = PortMapper::with_config(config);
// 2. 设置端口转发规则
// 将本地8080端口转发到远程Web服务
mapper.forward("127.0.0.1:8080", "web.example.com:80").await?;
// 将本地8081端口转发到远程数据库
mapper.forward("127.0.0.1:8081", "db.example.com:3306").await?;
// 3. 尝试NAT穿透建立P2P连接
let peer_ip = "123.45.67.89:54321"; // 对端公网IP和端口
let local_service = "127.0.0.1:8082"; // 本地需要暴露的服务
match mapper.punch_nat(peer_ip, local_service).await {
Ok(_) => println!("NAT穿透成功,P2P连接已建立"),
Err(e) => eprintln!("NAT穿透失败: {}", e),
}
println!("所有服务已启动:");
println!("- 本地8080端口 -> web.example.com:80");
println!("- 本地8081端口 -> db.example.com:3306");
println!("- P2P服务在8082端口");
// 4. 保持程序运行直到收到Ctrl+C信号
tokio::signal::ctrl_c().await?;
println!("正在关闭服务...");
Ok(())
}
常见使用场景
- 内网服务暴露:将内网开发的服务临时暴露到公网
- P2P应用:实现点对点直接通信,绕过NAT限制
- 服务迁移:在不中断服务的情况下迁移服务到新端口
- 负载测试:将测试流量转发到不同后端服务
注意事项
- 使用NAT穿透功能需要至少一端在非对称NAT后
- 端口转发会带来一定的性能开销
- 生产环境使用时建议添加适当的错误处理和日志记录
- 某些网络环境可能限制端口转发功能
portmapper库提供了强大的网络功能,但使用时应当遵守当地法律法规和网络使用政策。