jscanner

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit fe3162771744e9a21970f089d0fe52cef86a758e
parent 9cf19128b665293c56e4b3b2f978190a44257776
Author: Matthias Jaros <jaros@mailbox.org>
Date:   Mon, 26 Jan 2026 17:50:02 +0100

Added timeout to cli options

Diffstat:
Msrc/main/java/com/it_jaros/networkScanner/App.java | 6+++---
Msrc/main/java/com/it_jaros/networkScanner/CliParser.java | 9+++++++--
Msrc/main/java/com/it_jaros/networkScanner/ScanOptions.java | 2+-
Msrc/main/java/com/it_jaros/networkScanner/Scanner.java | 54++++++++++++++++++++++++++++++++----------------------
4 files changed, 43 insertions(+), 28 deletions(-)

diff --git a/src/main/java/com/it_jaros/networkScanner/App.java b/src/main/java/com/it_jaros/networkScanner/App.java @@ -6,9 +6,9 @@ public class App { public static void main(String[] args) { CliParser cliParser = new CliParser(); try { - ScanOptions target = cliParser.parseArgs(args); - Scanner scanner = new Scanner(target.openSocketLimit()); - List<ScanResult> openPorts = scanner.scanPorts(target); + ScanOptions options = cliParser.parseArgs(args); + Scanner scanner = new Scanner(options.openSocketLimit(), options.timeoutInMillis()); + List<ScanResult> openPorts = scanner.scanPorts(options); printResults(openPorts); } catch (IllegalArgumentException e) { System.out.println(e.getMessage()); diff --git a/src/main/java/com/it_jaros/networkScanner/CliParser.java b/src/main/java/com/it_jaros/networkScanner/CliParser.java @@ -13,6 +13,7 @@ public class CliParser { Set<String> targets = new HashSet<>(); int socketLimit = 1000; int delayInMillis = 0; + int timeoutInMillis = 1000; for (int i = 0; i < args.length; i++) { final String currentArg = args[i]; if (!currentArg.startsWith("-")) { @@ -30,6 +31,9 @@ public class CliParser { case "--delay", "-d": delayInMillis = Integer.parseInt(args[++i]); break; + case "--timeout", "-t": + timeoutInMillis = Integer.parseInt(args[++i]); + break; default: throw new IllegalArgumentException("No such param " + currentArg); } @@ -40,9 +44,9 @@ public class CliParser { } System.out.printf( - "Scanning targets '%s' with socketLimit(%s), delayInMillis(%s) \n", targets, socketLimit, delayInMillis); + "Scanning targets '%s' with socketLimit(%s), delayInMillis(%s), timeoutInMillis(%s)\n", targets, socketLimit, delayInMillis, timeoutInMillis); - return new ScanOptions(targets.stream().toList(), socketLimit, delayInMillis); + return new ScanOptions(targets.stream().toList(), socketLimit, delayInMillis, timeoutInMillis); } public void usageAndExit() { @@ -53,6 +57,7 @@ public class CliParser { Options: --delay, -d: Waiting period in millis for connection attempts for a host --socketLimit, -sl: Socket Connection limit for a host + --timeout, -t: Timeout per connection attempt Examples: java -jar scanner.jar localhost diff --git a/src/main/java/com/it_jaros/networkScanner/ScanOptions.java b/src/main/java/com/it_jaros/networkScanner/ScanOptions.java @@ -2,4 +2,4 @@ package com.it_jaros.networkScanner; import java.util.List; -public record ScanOptions(List<String> targets, int openSocketLimit, int delayInMillis) {} +public record ScanOptions(List<String> targets, int openSocketLimit, int delayInMillis, int timeoutInMillis) {} diff --git a/src/main/java/com/it_jaros/networkScanner/Scanner.java b/src/main/java/com/it_jaros/networkScanner/Scanner.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.net.ConnectException; import java.net.InetSocketAddress; import java.net.Socket; +import java.net.SocketTimeoutException; import java.util.ArrayList; import java.util.List; import java.util.Queue; @@ -17,14 +18,18 @@ import java.util.concurrent.locks.LockSupport; public class Scanner { - private Counter counter = new Counter(); - private Semaphore socketCap; + private final Counter counter = new Counter(); + private final Semaphore socketCap; + private final int timeoutInMillis; - public Scanner(int socketLimit) { + public Scanner(int socketLimit, int timeoutInMillis) { + this.timeoutInMillis = timeoutInMillis; socketCap = new Semaphore(socketLimit); } - public Scanner() {} + public Scanner() { + this(1000, 1000); + } public List<ScanResult> scanPorts(ScanOptions target) { return scanPorts(target.targets(), target.delayInMillis()); @@ -48,26 +53,31 @@ public class Scanner { for (int port = 1; port < 65536; port++) { final int currentPort = port; executor.submit(() -> { - if (delayInNanos > 0) { - long mySlot = nextStartNanos.getAndAdd(delayInNanos); - long wait = mySlot - System.nanoTime(); - if (wait > 0) - LockSupport.parkNanos(wait); - } - socketCap.acquireUninterruptibly(); - counter.inc(); - try (Socket socket = new Socket()) { - socket.connect(new InetSocketAddress(target, currentPort), 10000); - openPorts.add(currentPort); - } catch (ConnectException ignored) { - } catch (IOException e) { - System.out.println(e.getClass().getSimpleName() + ": " + e.getMessage()); - } finally { - counter.dec(); - socketCap.release(); - } + scanPortsAsync(target, delayInNanos, nextStartNanos, openPorts, currentPort); }); } return new ScanResult(target, openPorts); } + + private void scanPortsAsync(String target, long delayInNanos, AtomicLong nextStartNanos, Queue<Integer> openPorts, + int currentPort) { + if (delayInNanos > 0) { + long mySlot = nextStartNanos.getAndAdd(delayInNanos); + long wait = mySlot - System.nanoTime(); + if (wait > 0) + LockSupport.parkNanos(wait); + } + socketCap.acquireUninterruptibly(); + counter.inc(); + try (Socket socket = new Socket()) { + socket.connect(new InetSocketAddress(target, currentPort), timeoutInMillis); + openPorts.add(currentPort); + } catch (ConnectException | SocketTimeoutException ignored) { + } catch (IOException e) { + System.out.println(e.getClass().getSimpleName() + ": " + e.getMessage()); + } finally { + counter.dec(); + socketCap.release(); + } + } }