当前位置:   article > 正文

rust实现简易端口扫描_rust 检查端口

rust 检查端口

前言

要实现端口扫描, 只需要遍历端口, 然后尝试连接, 成功就表示是开放的

注解

Arguments结构体

表示接收到的命令行参数, 有ip地址, 要使用的线程数(每次用多少线程来同时请求端口)

scan方法

扫描端口, 尝试连接, 成功了就在屏幕输出一个 .

main方法

接收命令行参数, 创建Arguments对象, 创建时会判断参数个数, 如果不合规就会退出程序;

开 指定线程数 个端口, 然后开 指定线程数 个线程去同时请求这些的端口

代码

  1. use std::env;
  2. use std::io::{ self, Write };
  3. use std::net::{ IpAddr, TcpStream };
  4. use std::str::FromStr;
  5. use std::process;
  6. use std::sync::mpsc::{ Sender, channel };
  7. use std::thread;
  8. // 最大端口
  9. const MAX: u16 = 65535;
  10. struct Arguments {
  11. flag: String,
  12. ipaddr: IpAddr, // ip地址
  13. threads: u16, // 线程数
  14. }
  15. impl Arguments {
  16. fn new(args: &[String]) -> Result<Arguments, &'static str> {
  17. if args.len() < 2 {
  18. return Err("not enough arguments");
  19. } else if args.len() > 4 {
  20. return Err("too many arguments");
  21. }
  22. let f = args[1].clone();
  23. if let Ok(ipaddr) = IpAddr::from_str(&f) {
  24. return Ok(Arguments { flag: String::from(""), ipaddr, threads: 4 });
  25. } else {
  26. let flag = args[1].clone();
  27. if flag.contains("-h") || flag.contains("-help") || args.len() == 2 {
  28. println!(
  29. "Usage: -j to select how many threads you want\r\n -h or -help to show this help message"
  30. );
  31. return Err("help");
  32. } else if flag.contains("-h") || flag.contains("-help") {
  33. return Err("too many arguments");
  34. } else if flag.contains("-j") {
  35. let ipaddr = match IpAddr::from_str(&args[3]) {
  36. Ok(s) => s,
  37. Err(_) => {
  38. return Err("not a valid IpAddr;must be ipv4 or ipv6");
  39. }
  40. };
  41. let threads = match args[2].parse::<u16>() {
  42. Ok(s) => s,
  43. Err(_) => {
  44. return Err("failed to parse thread number");
  45. }
  46. };
  47. return Ok(Arguments { threads, flag, ipaddr });
  48. } else {
  49. return Err("Invalid syntax");
  50. }
  51. }
  52. }
  53. }
  54. // 扫描端口
  55. fn scan(tx: Sender<u16>, start_port: u16, addr: IpAddr, num_threads: u16) {
  56. let mut port: u16 = start_port + 1;
  57. loop {
  58. match TcpStream::connect((addr, port)) {
  59. Ok(_) => {
  60. print!(".");
  61. io::stdout().flush().unwrap();
  62. tx.send(port).unwrap();
  63. }
  64. Err(_) => {}
  65. }
  66. if MAX - port <= num_threads {
  67. break;
  68. }
  69. port += num_threads;
  70. }
  71. }
  72. fn main() {
  73. // 接收命令行参数
  74. let args: Vec<String> = env::args().collect();
  75. let program = args[0].clone();
  76. let arguments = Arguments::new(&args).unwrap_or_else(|err| {
  77. if err.contains("help") {
  78. process::exit(0);
  79. } else {
  80. eprintln!("{} problem parsing arguments: {}", program, err);
  81. process::exit(0);
  82. }
  83. });
  84. let num_threads = arguments.threads;
  85. let addr = arguments.ipaddr;
  86. let (tx, rx) = channel();
  87. for i in 0..num_threads {
  88. let tx = tx.clone();
  89. thread::spawn(move || {
  90. scan(tx, i, addr, num_threads);
  91. });
  92. }
  93. let mut out = vec![];
  94. drop(tx);
  95. for p in rx {
  96. out.push(p);
  97. }
  98. println!("");
  99. out.sort();
  100. for v in out {
  101. println!("{} is open", v);
  102. }
  103. }

测试

  1. cargo run -- -h
  2. cargo run -- -j 1000 192.168.1.1
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/640996
推荐阅读
相关标签
  

闽ICP备14008679号