-
-
Save rust-play/04022c1a9e0e7bcbc8bbab161368b69d to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use std::net::{TcpListener, TcpStream, /*ToSocketAddrs, */SocketAddr}; | |
| use std::time::Duration; | |
| use std::thread; | |
| use std::io::{self, Read, Write}; | |
| // --- Configuration --- | |
| const TARGET_IP: &str = "127.0.0.1"; // The IP the scanner checks | |
| const TIMEOUT_MS: u64 = 500; // Connection timeout in milliseconds | |
| // --------------------- | |
| fn main() -> io::Result<()> { | |
| println!("--- π¦ Combined Bind and Scan Script ---"); | |
| let timeout = Duration::from_millis(TIMEOUT_MS); | |
| // Create a channel to pass the dynamically chosen port from the server thread to the main thread | |
| let (tx, rx) = std::sync::mpsc::channel(); | |
| // 1. START THE SERVER THREAD (BIND) | |
| let server_handle = thread::spawn(move || { | |
| // The fix: explicitly annotating the type as SocketAddr | |
| let bind_addr: SocketAddr = "0.0.0.0:0".parse().unwrap(); | |
| println!("\n[SERVER] Attempting to bind to: {}", bind_addr); | |
| let listener = match TcpListener::bind(bind_addr) { | |
| Ok(l) => l, | |
| Err(e) => { | |
| eprintln!("[SERVER] β Failed to bind: {}", e); | |
| // Return an error to stop the thread and cause join() to fail | |
| return Err(e); | |
| } | |
| }; | |
| let local_addr = listener.local_addr()?; | |
| let chosen_port = local_addr.port(); | |
| println!("[SERVER] β Listener bound to: {}", local_addr); | |
| println!("[SERVER] π Dynamic port chosen: {}", chosen_port); | |
| // Send the chosen port to the main thread for the scanner | |
| tx.send(chosen_port).unwrap(); | |
| // Server waits for and handles a single connection | |
| println!("[SERVER] Waiting for a connection..."); | |
| match listener.accept() { | |
| Ok((mut stream, addr)) => { | |
| println!("[SERVER] π€ Connection accepted from: {}", addr); | |
| let mut buffer = [0; 128]; | |
| let bytes_read = stream.read(&mut buffer).expect("Failed to read"); | |
| let message = String::from_utf8_lossy(&buffer[..bytes_read]); | |
| println!("[SERVER] Received: \"{}\"", message); | |
| stream.write_all(b"ACK from server").expect("Failed to write"); | |
| println!("[SERVER] Sent 'ACK from server' and closing connection."); | |
| } | |
| Err(e) => eprintln!("[SERVER] Connection error: {}", e), | |
| } | |
| // Return a successful result for the thread | |
| Ok(()) | |
| }); | |
| // 2. WAIT FOR THE DYNAMIC PORT | |
| let server_port = rx.recv().expect("Failed to receive port from server thread."); | |
| // 3. START THE CLIENT/SCANNER (SCAN) | |
| let scanner_handle = thread::spawn(move || { | |
| // Give the server a moment to enter the accept loop | |
| thread::sleep(Duration::from_millis(100)); | |
| println!("\n[SCANNER] Starting connection attempt..."); | |
| let address = format!("{}:{}", TARGET_IP, server_port); | |
| match TcpStream::connect_timeout(&address.parse().unwrap(), timeout) { | |
| Ok(mut stream) => { | |
| println!("[SCANNER] [+] Port {} is OPEN on {}", server_port, TARGET_IP); | |
| stream.write_all(b"Hello Server!").expect("Client failed to send data"); | |
| let mut response = [0; 128]; | |
| let bytes_read = stream.read(&mut response).expect("Client failed to read response"); | |
| let message = String::from_utf8_lossy(&response[..bytes_read]); | |
| println!("[SCANNER] Received response: \"{}\"", message); | |
| }, | |
| Err(e) if e.kind() == io::ErrorKind::TimedOut => { | |
| println!("[SCANNER] [-] Port {} Timed Out.", server_port); | |
| }, | |
| Err(e) => { | |
| println!("[SCANNER] [-] Port {} Closed/Error: {}", server_port, e); | |
| } | |
| } | |
| }); | |
| // 4. WAIT FOR BOTH THREADS TO FINISH | |
| scanner_handle.join().expect("Scanner thread panicked!"); | |
| // The ? propagates the io::Result<()>, handling any bind error from the server thread | |
| server_handle.join().expect("Server thread panicked!")?; | |
| println!("\n--- Script Finished ---"); | |
| Ok(()) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment