Rust网络状态监控库netstat2的使用,netstat2提供高效网络连接统计与端口监控功能
Rust网络状态监控库netstat2的使用
netstat2是一个跨平台库,用于检索网络套接字信息。它通过使用低级操作系统API而不是命令行工具来实现高效性能,并提供统一的接口和返回数据结构。
安装
在Cargo.toml中添加依赖:
[dependencies]
netstat2 = "0.11"
示例代码
以下是内容中提供的示例:
use netstat2::{get_sockets_info, AddressFamilyFlags, ProtocolFlags, ProtocolSocketInfo};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let af_flags = AddressFamilyFlags::IPV4 | AddressFamilyFlags::IPV6;
let proto_flags = ProtocolFlags::TCP | ProtocolFlags::UDP;
let sockets_info = get_sockets_info(af_flags, proto_flags)?;
for si in sockets_info {
match si.protocol_socket_info {
ProtocolSocketInfo::Tcp(tcp_si) => println!(
"TCP {}:{} -> {}:{} {:?} - {}",
tcp_si.local_addr,
tcp_si.local_port,
tcp_si.remote_addr,
tcp_si.remote_port,
si.associated_pids,
tcp_si.state
),
ProtocolSocketInfo::Udp(udp_si) => println!(
"UDP {}:{} -> *:* {:?}",
udp_si.local_addr, udp_si.local_port, si.associated_pids
),
}
}
Ok(())
}
完整示例
以下是一个更完整的网络状态监控示例,包含更多功能展示:
use netstat2::{
get_sockets_info, AddressFamilyFlags, ProtocolFlags, ProtocolSocketInfo,
TcpState, SocketInfo
};
use std::error::Error;
// 网络连接统计结构体
struct ConnectionStats {
total: usize,
tcp: usize,
udp: usize,
established: usize,
listening: usize,
}
fn main() -> Result<(), Box<dyn Error>> {
// 设置要查询的协议类型
let af_flags = AddressFamilyFlags::IPV4 | AddressFamilyFlags::IPV6;
let proto_flags = ProtocolFlags::TCP | ProtocolFlags::UDP;
// 获取所有套接字信息
let sockets_info = get_sockets_info(af_flags, proto_flags)?;
// 初始化统计
let mut stats = ConnectionStats {
total: 0,
tcp: 0,
udp: 0,
established: 0,
listening: 0,
};
// 遍历所有套接字并统计信息
for si in sockets_info {
stats.total += 1;
match si.protocol_socket_info {
ProtocolSocketInfo::Tcp(tcp_si) => {
stats.tcp += 1;
// 统计TCP状态
match tcp_si.state {
TcpState::Established => stats.established += 1,
TcpState::Listen => stats.listening += 1,
_ => (),
}
print_tcp_info(&si, &tcp_si);
}
ProtocolSocketInfo::Udp(udp_si) => {
stats.udp += 1;
print_udp_info(&si, &udp_si);
}
}
}
// 打印统计信息
println!("\n=== 网络连接统计 ===");
println!("总连接数: {}", stats.total);
println!("TCP连接数: {}", stats.tcp);
println!(" - 已建立: {}", stats.established);
println!(" - 监听中: {}", stats.listening);
println!("UDP连接数: {}", stats.udp);
Ok(())
}
// 打印TCP连接信息
fn print_tcp_info(si: &SocketInfo, tcp_si: &netstat2::TcpSocketInfo) {
println!(
"TCP {}:{} -> {}:{} (PID: {:?}) - 状态: {:?}",
tcp_si.local_addr,
tcp_si.local_port,
tcp_si.remote_addr,
tcp_si.remote_port,
si.associated_pids,
tcp_si.state
);
}
// 打印UDP连接信息
fn print_udp_info(si: &SocketInfo, udp_si: &netstat2::UdpSocketInfo) {
println!(
"UDP {}:{} (PID: {:?})",
udp_si.local_addr,
udp_si.local_port,
si.associated_pids
);
}
实现细节
- 在Windows上,该库使用GetExtendedTcpTable和GetExtendedUdpTable (iphlpapi)
- 在Linux和Android上,它使用NETLINK_INET_DIAG协议并通过遍历procfs进行pid查找
- 在macOS和iOS上,它使用proc_pidfdinfo
许可证
可选择以下两种许可证之一:
- Apache License, Version 2.0
- MIT license
netstat2库提供了一种高效的方式来监控网络连接状态和端口使用情况,适用于需要网络监控功能的Rust应用程序开发。
1 回复
Rust网络状态监控库netstat2使用指南
简介
netstat2是一个高效的Rust库,用于监控网络连接状态和端口使用情况。它提供了跨平台的网络统计功能,可以替代系统自带的netstat命令,并以编程方式获取网络连接信息。
主要功能
- 获取所有活跃的网络连接
- 监控端口使用情况
- 区分TCP和UDP连接
- 获取连接相关的进程信息
- 支持IPv4和IPv6
使用方法
添加依赖
首先在Cargo.toml中添加依赖:
[dependencies]
netstat2 = "0.2"
基本示例
use netstat2::{get_sockets_info, AddressFamilyFlags, ProtocolFlags, ProtocolSocketInfo};
fn main() {
// 获取所有TCP和UDP连接
let af_flags = AddressFamilyFlags::IPV4 | AddressFamilyFlags::IPV6;
let proto_flags = ProtocolFlags::TCP | ProtocolFlags::UDP;
match get_sockets_info(af_flags, proto_flags) {
Ok(sockets) => {
for socket in sockets {
match socket {
ProtocolSocketInfo::Tcp(tcp) => {
println!("TCP connection: {}:{} -> {}:{} (PID: {:?})",
tcp.local_addr, tcp.local_port,
tcp.remote_addr, tcp.remote_port,
tcp.associated_pids);
},
ProtocolSocketInfo::Udp(udp) => {
println!("UDP connection: {}:{} (PID: {:?})",
udp.local_addr, udp.local_port,
udp.associated_pids);
}
}
}
},
Err(e) => eprintln!("Error: {}", e),
}
}
监控特定端口
use netstat2::{get_sockets_info, AddressFamilyFlags, ProtocolFlags};
fn is_port_in_use(port: u16) -> bool {
let af_flags = AddressFamilyFlags::IPV4 | AddressFamilyFlags::IPV6;
let proto_flags = ProtocolFlags::TCP | ProtocolFlags::UDP;
match get_sockets_info(af_flags, proto_flags) {
Ok(sockets) => sockets.iter().any(|s| match s {
ProtocolSocketInfo::Tcp(tcp) => tcp.local_port == port,
ProtocolSocketInfo::Udp(udp) => udp.local_port == port,
}),
Err(_) => false,
}
}
fn main() {
let port = 8080;
if is_port_in_use(port) {
println!("Port {} is in use!", port);
} else {
println!("Port {} is available", port);
}
}
获取进程网络连接统计
use netstat2::{get_sockets_info, AddressFamilyFlags, ProtocolFlags, ProtocolSocketInfo};
fn get_process_connections(pid: u32) {
let af_flags = AddressFamilyFlags::IPV4 | AddressFamilyFlags::IPV6;
let proto_flags = ProtocolFlags::TCP | ProtocolFlags::UDP;
match get_sockets_info(af_flags, proto_flags) {
Ok(sockets) => {
println!("Connections for PID {}:", pid);
for socket in sockets {
let pids = match &socket {
ProtocolSocketInfo::Tcp(tcp) => &tcp.associated_pids,
ProtocolSocketInfo::Udp(udp) => &udp.associated_pids,
};
if pids.contains(&pid) {
println!("{:?}", socket);
}
}
},
Err(e) => eprintln!("Error: {}", e),
}
}
fn main() {
get_process_connections(1234); // 替换为你想检查的PID
}
完整示例
以下是一个综合使用netstat2库的完整示例,展示了如何获取网络连接、检查端口使用情况以及监控特定进程的网络活动:
use netstat2::{
get_sockets_info,
AddressFamilyFlags,
ProtocolFlags,
ProtocolSocketInfo
};
fn main() {
// 示例1:获取所有网络连接
println!("=== 所有网络连接 ===");
list_all_connections();
// 示例2:检查端口是否被占用
println!("\n=== 端口检查 ===");
check_ports(&[8080, 3000, 6379]);
// 示例3:监控特定进程的网络活动
println!("\n=== 进程网络监控 ===");
monitor_process_connections(std::process::id()); // 监控当前进程
}
/// 列出所有网络连接
fn list_all_connections() {
let af_flags = AddressFamilyFlags::IPV4 | AddressFamilyFlags::IPV6;
let proto_flags = ProtocolFlags::TCP | ProtocolFlags::UDP;
match get_sockets_info(af_flags, proto_flags) {
Ok(sockets) => {
for socket in sockets {
match socket {
ProtocolSocketInfo::Tcp(tcp) => {
println!("TCP {}:{} -> {}:{} PID:{:?}",
tcp.local_addr, tcp.local_port,
tcp.remote_addr, tcp.remote_port,
tcp.associated_pids);
},
ProtocolSocketInfo::Udp(udp) => {
println!("UDP {}:{} PID:{:?}",
udp.local_addr, udp.local_port,
udp.associated_pids);
}
}
}
},
Err(e) => eprintln!("获取连接失败: {}", e),
}
}
/// 检查一组端口是否被占用
fn check_ports(ports: &[u16]) {
for &port in ports {
println!("端口 {}: {}", port,
if is_port_in_use(port) { "使用中" } else { "可用" });
}
}
/// 检查单个端口是否被使用
fn is_port_in_use(port: u16) -> bool {
let af_flags = AddressFamilyFlags::IPV4 | AddressFamilyFlags::IPV6;
let proto_flags = ProtocolFlags::TCP | ProtocolFlags::UDP;
match get_sockets_info(af_flags, proto_flags) {
Ok(sockets) => sockets.iter().any(|s| match s {
ProtocolSocketInfo::Tcp(tcp) => tcp.local_port == port,
ProtocolSocketInfo::Udp(udp) => udp.local_port == port,
}),
Err(_) => false,
}
}
/// 监控特定进程的网络连接
fn monitor_process_connections(pid: u32) {
let af_flags = AddressFamilyFlags::IPV4 | AddressFamilyFlags::IPV6;
let proto_flags = ProtocolFlags::TCP | ProtocolFlags::UDP;
match get_sockets_info(af_flags, proto_flags) {
Ok(sockets) => {
let process_sockets: Vec<_> = sockets.into_iter()
.filter(|s| match s {
ProtocolSocketInfo::Tcp(tcp) => tcp.associated_pids.contains(&pid),
ProtocolSocketInfo::Udp(udp) => udp.associated_pids.contains(&pid),
})
.collect();
println!("进程 {} 有 {} 个活跃连接:", pid, process_sockets.len());
for socket in process_sockets {
println!(" - {:?}", socket);
}
},
Err(e) => eprintln!("获取进程连接失败: {}", e),
}
}
注意事项
- 在Linux系统上需要足够的权限才能获取所有连接信息
- 不同平台(Windows/Linux/macOS)的实现细节可能有所不同
- 频繁调用可能会对系统性能产生一定影响
netstat2库为Rust开发者提供了强大的网络监控能力,特别适合需要程序化网络状态监控的应用场景。