From 8d40ec4bff17b8ad04008a8b851bc26aafcfc72b Mon Sep 17 00:00:00 2001 From: Matthias Jaros Date: Mon, 9 Mar 2026 14:41:39 +0100 Subject: Finally refactored structure of virtual threads in a way that makes sense and feels more natural. Each layer, host target and target port scan has it's own executor and is responsible for it's own updates. return statement is called only when everything is finished --- .../java/com/it_jaros/networkScanner/Scanner.java | 56 ++++++++++++++-------- 1 file changed, 36 insertions(+), 20 deletions(-) (limited to 'src/main/java/com/it_jaros/networkScanner/Scanner.java') diff --git a/src/main/java/com/it_jaros/networkScanner/Scanner.java b/src/main/java/com/it_jaros/networkScanner/Scanner.java index cfef136..b136182 100644 --- a/src/main/java/com/it_jaros/networkScanner/Scanner.java +++ b/src/main/java/com/it_jaros/networkScanner/Scanner.java @@ -9,8 +9,10 @@ import java.util.ArrayList; import java.util.List; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.Future; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -37,13 +39,22 @@ public class Scanner { public List scanTargets(List targets, String ports) { List results = new ArrayList<>(); + List> futures = new ArrayList<>(); + progressBar.start(); try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();) { - progressBar.start(); for (String target : targets) { - ScanResult result = scanTargetPorts(target, ports, executor); - results.add(result); - progressBar.submit(result.progress()); + futures.add(executor.submit(() -> { + return scanTargetPorts(target, ports); + })); } + + futures.forEach((f) -> { + try { + results.add(f.get()); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + }); } progressBar.stop(); @@ -51,27 +62,32 @@ public class Scanner { return results; } - private ScanResult scanTargetPorts(String target, String ports, ExecutorService executor) { + private ScanResult scanTargetPorts(String target, String ports) { PortRange portRange = new PortRange(ports); - Progress progress = new Progress(target, portRange.getTotal(), new AtomicInteger(), - new AtomicInteger()); AtomicLong scanSlotFactory = new AtomicLong(System.nanoTime()); Queue openPorts = new ConcurrentLinkedQueue<>(); - while (portRange.hasNext()) { - final int currentPort = portRange.next(); - executor.submit(() -> { - try { - waitForSlot(scanSlotFactory); - if (isTargetPortOpen(target, currentPort)) { - openPorts.add(currentPort); - progressBar.onPortOpen(progress); + + Progress progress = new Progress(target, portRange.getTotal(), new AtomicInteger(), new AtomicInteger()); + progressBar.submit(progress); + + try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();) { + while (portRange.hasNext()) { + final int currentPort = portRange.next(); + executor.submit(() -> { + try { + waitForSlot(scanSlotFactory); + if (isTargetPortOpen(target, currentPort)) { + openPorts.add(currentPort); + progress.open().incrementAndGet(); + } + } finally { + progress.done().incrementAndGet(); } - } finally { - progressBar.onPortFinished(progress); - } - }); + }); + } } - return new ScanResult(target, openPorts, progress); + + return new ScanResult(target, openPorts); } private void waitForSlot(AtomicLong scanSlotFactory) { -- cgit v1.3.1