Как исправить данную проблему в коде ниже, чтобы программа продолжала работать, если значение переменной `my_host` изменится на другой адрес, например, `192.168.1.0` или любой другой? ```rust use std::net::TcpStream; fn tcp_scan(host: String) { for port in 1..1024 { let mut ip = String::from(&host); ip.push_str(":"); ip.push_str(&port.to_string()); if let Ok(_) = TcpStream::connect(&ip) { println!("This {} port is open", ip); } else { continue; } } } fn main() { let my_host = String::from("192.168.1.0"); tcp_scan(my_host); } ```
Проблема заключается в том, что программа введена в интерактивном режиме, и при каждом вводе значения переменной `my_host` программа завершается и начинает сканирование заново. Чтобы исправить эту проблему, можно использовать цикл, который будет просить пользователя вводить адрес хоста до тех пор, пока не будет введено ключевое слово для завершения программы. Ниже приведен исправленный код: ```rust use std::io::{self, Write}; use std::net::TcpStream; fn tcp_scan(host: &str) { for port in 1..1024 { let mut ip = String::from(host); ip.push_str(":"); ip.push_str(&port.to_string()); if let Ok(_) = TcpStream::connect(&ip) { println!("This {} port is open", ip); } else { continue; } } } fn main() { loop { print!("Enter the host address (or 'exit' to quit): "); io::stdout().flush().unwrap(); let mut input = String::new(); io::stdin().read_line(&mut input).unwrap(); let input = input.trim(); if input == "exit" { break; } tcp_scan(&input); } } ``` Теперь программа будет запрашивать у пользователя ввод адреса хоста, а после завершения сканирования будет ждать следующего ввода адреса хоста. Если пользователь введет "exit", то программа завершится.
Несколько советов: - Проверь, что проблема возникает на этой строке кода: TcpStream::connect(&ip). Это можно сделать, добавив логирование или профилирование. Лучше прийти на форум уже немного подготовленным, чем просто с зависающей программой. - Учти, что TCP протокол требует ресурсы. Каждый новый сокет выделяет память для работы с опциями протокола, такими как восстановление потерянных пакетов. Проверь, как у тебя работает приложение по скорости. Например, проверь, насколько быстро оно обрабатывает ответы от портов, которые не отвечают. Это тоже протокольная ситуация и ее нужно обрабатывать, не полагаясь на дефолтные тайминги. - Возможно, некоторые промышленные утилиты-сканеры, такие как nmap, не используют создание сокета. Они работают на уровне IP-протокола, отправляя асинхронные SYN-пакеты и обрабатывая ответы. В результате создается сокет без буфера. Это может быть не совсем честно с точки зрения полноценного протокола, но достаточно, чтобы проверить, пришел ли ACK. Посмотри, какие возможности предлагает Rust в части IP-программирования.