网站首页 > 基础教程 正文
1,Cargo.toml
[package]
name = "ip-scan"
version = "0.1.0"
edition = "2024"
[dependencies]
clap = { version = "3.2.25", features = ["derive"] }
2, main.rs
use clap::{App, Arg};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::sync::mpsc;
use std::sync::Arc;
use std::thread;
use std::time::Duration;
use std::net::TcpStream;
fn main() {
let matches = App::new("IP Scanner")
.version("1.0")
.author("Your Name")
.about("Scans IP addresses and ports")
.arg(
Arg::with_name("start_ip")
.short('s')
.long("start")
.value_name("START_IP")
.help("Starting IP address")
.takes_value(true)
.required(true),
)
.arg(
Arg::with_name("end_ip")
.short('e')
.long("end")
.value_name("END_IP")
.help("Ending IP address")
.takes_value(true)
.required(true),
)
.arg(
Arg::with_name("start_port")
.short('p')
.long("port")
.value_name("START_PORT")
.help("Starting port (default: 1)")
.takes_value(true),
)
.arg(
Arg::with_name("end_port")
.short('P')
.long("ports")
.value_name("END_PORT")
.help("Ending port (default: 1000)")
.takes_value(true),
)
.arg(
Arg::with_name("threads")
.short('t')
.long("threads")
.value_name("THREADS")
.help("Number of threads (default: 100)")
.takes_value(true),
)
.get_matches();
let start_ip_str = matches.value_of("start_ip").unwrap();
let end_ip_str = matches.value_of("end_ip").unwrap();
let start_ip = parse_ip(start_ip_str).expect("Invalid start IP address");
let end_ip = parse_ip(end_ip_str).expect("Invalid end IP address");
let start_port = matches.value_of("start_port").unwrap_or("1").parse::<u16>().expect("Invalid start port");
let end_port = matches.value_of("end_port").unwrap_or("1000").parse::<u16>().expect("Invalid end port");
let num_threads = matches.value_of("threads").unwrap_or("100").parse::<usize>().expect("Invalid thread count");
println!("Scanning IP range: {} - {}", start_ip, end_ip);
println!("Scanning ports: {} - {}", start_port, end_port);
println!("Using {} threads", num_threads);
let (tx, rx) = mpsc::channel();
let tx = Arc::new(tx);
let mut handles = vec![];
// Split the port range into chunks for each thread
let total_ports = (end_port - start_port + 1) as usize;
let ports_per_thread = (total_ports + num_threads - 1) / num_threads;
for thread_id in 0..num_threads {
let tx = Arc::clone(&tx);
let start_port_chunk = start_port + (thread_id * ports_per_thread) as u16;
let end_port_chunk = std::cmp::min(start_port_chunk + ports_per_thread as u16 - 1, end_port);
let handle = thread::spawn(move || {
// Iterate over the IP range
for ip_int in ip_to_int(start_ip)..=ip_to_int(end_ip) {
let ip = int_to_ip(ip_int);
// Scan the assigned ports for this IP
for port in start_port_chunk..=end_port_chunk {
let socket_addr = SocketAddr::new(IpAddr::V4(ip), port);
if TcpStream::connect_timeout(&socket_addr, Duration::from_secs(1)).is_ok() {
tx.send((ip, port)).unwrap();
}
}
}
});
handles.push(handle);
}
// Drop the original sender so the receiver knows when all threads are done
drop(tx);
// Collect and print the results
let mut results = vec![];
for (ip, port) in rx {
results.push((ip, port));
}
// Wait for all threads to finish
for handle in handles {
handle.join().unwrap();
}
// Sort the results by IP and port
results.sort_by_key(|&(ip, port)| (ip_to_int(ip), port));
// Print the results
println!("\nScan Results:");
println!("=============");
for (ip, port) in results {
println!("{}:{} is open", ip, port);
}
}
fn parse_ip(ip_str: &str) -> Option<Ipv4Addr> {
ip_str.parse().ok()
}
fn ip_to_int(ip: Ipv4Addr) -> u32 {
let octets = ip.octets();
(octets[0] as u32) << 24 | (octets[1] as u32) << 16 | (octets[2] as u32) << 8 | (octets[3] as u32)
}
fn int_to_ip(int: u32) -> Ipv4Addr {
Ipv4Addr::new(
((int >> 24) & 0xFF) as u8,
((int >> 16) & 0xFF) as u8,
((int >> 8) & 0xFF) as u8,
(int & 0xFF) as u8,
)
}
3, 运行 cargo build --release
./target/release/ip-scan -s 192.168.5.110 -e 192.168.5.120 -p 80 -P 80 -t 100
猜你喜欢
- 2025-06-12 实例解析C++多线程并发---异步编程
- 2025-06-12 Go与Rust多线程编程深度对比(go和rust2021)
- 2025-06-12 Rust + Slint异步UI编程的奥秘,让你的应用永不假死!
- 2025-06-12 25道C++经典面试题详解,附全套学习资料免费领!
- 2025-06-12 Rust并发编程中的内部可变性(rust 并发)
- 2025-06-12 深入解析C++并发编程:从多线程到现代C++并发库
- 2025-06-12 C++ 创建新线程的核心指南:从基础到关键要点
- 2025-06-12 Rust 语言的借用规则:构筑安全内存管理体系的核心保障机制
- 2025-06-12 C++线程池的原理和方法实践(c线程池实现原理)
- 2025-06-12 你们在编程时遇到过什么离谱的bug吗?
- 最近发表
- 标签列表
-
- jsp (69)
- gitpush (78)
- gitreset (66)
- python字典 (67)
- dockercp (63)
- gitclone命令 (63)
- dockersave (62)
- linux命令大全 (65)
- pythonif (86)
- location.href (69)
- dockerexec (65)
- tail-f (79)
- queryselectorall (63)
- location.search (79)
- bootstrap教程 (74)
- deletesql (62)
- linuxgzip (68)
- 字符串连接 (73)
- html标签 (69)
- c++初始化列表 (64)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)