summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Matthias Jaros <jarlucmat@mailbox.org>2026-08-04 18:30:47 +0200
committerGravatar Matthias Jaros <jarlucmat@mailbox.org>2026-08-04 22:07:14 +0200
commit82013ee45cb8258487952de6d0a20fa66876bfbf (patch)
treec555beb1dd5ed43c61fb49f45b0fc1f1d5d33170
parent2f6cd5bab5870e22d3fb8c25e732aebd35277346 (diff)
Use SocketChannel for better timeout control
-rw-r--r--src/main/java/com/it_jaros/jscanner/Scanner.java34
1 files changed, 29 insertions, 5 deletions
diff --git a/src/main/java/com/it_jaros/jscanner/Scanner.java b/src/main/java/com/it_jaros/jscanner/Scanner.java
index 9f5ac52..5277327 100644
--- a/src/main/java/com/it_jaros/jscanner/Scanner.java
+++ b/src/main/java/com/it_jaros/jscanner/Scanner.java
@@ -3,6 +3,9 @@ package com.it_jaros.jscanner;
import java.io.IOException;
import java.io.InputStream;
import java.net.*;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.*;
@@ -347,11 +350,32 @@ public class Scanner implements AutoCloseable {
socketLimit.acquire();
scan.socketStart();
- try (Socket socket = new Socket()) {
- socket.connect(new InetSocketAddress(host, port), timeoutInMillis);
- result.setState(PortState.OPEN);
- if (bannerRecognition) {
- result.setBanner(getBanner(socket));
+ try(
+ SocketChannel socketChannel = SocketChannel.open();
+ Selector isOpen = Selector.open()
+ ) {
+ socketChannel.configureBlocking(false);
+ SelectionKey isOpenKey = socketChannel.register(isOpen, SelectionKey.OP_CONNECT);
+ socketChannel.connect(new InetSocketAddress(host, port));
+ long deadlineNanos = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(timeoutInMillis);
+ long waitInMillis = Math.min(timeoutInMillis, 5);
+ while (isOpenKey.isValid() && !isOpenKey.isConnectable()) {
+ if (isOpen.select(waitInMillis) == 1) {
+ if (socketChannel.finishConnect()) {
+ result.setState(PortState.OPEN);
+ //if (bannerRecognition) {
+ // result.setBanner(getBanner(socket));
+ //}
+ } else {
+ result.setState(PortState.FILTERED);
+ }
+ break;
+ }
+
+ if (deadlineNanos - System.nanoTime() < 0) {
+ result.setState(PortState.FILTERED);
+ break;
+ }
}
} catch (SocketTimeoutException ignored) {
result.setState(PortState.FILTERED);