google-site-verification: google61fe8ba583a51912.html
Port Scanner with Sockets in Java

A comprehensive, multi-threaded port scanner implementation using Java Sockets with both command-line and GUI interfaces.

Project Structure

PortScanner/ ├── src/ │ ├── com/portscanner/ │ │ ├── core/ │ │ ├── gui/ │ │ ├── models/ │ │ └── utils/ │ └── resources/ └── lib/

Core Implementation

Port Scanner Engine

package com.portscanner.core; import com.portscanner.models.ScanResult; import com.portscanner.models.ScanConfig; import java.net.*; import java.io.*; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; public class PortScanner { private final ExecutorService executorService; private final int timeout; private final int maxThreads; private final AtomicInteger completedScans; private final AtomicInteger openPortsFound; private volatile boolean isScanning; private List<ScanResult> results; public PortScanner() { this(1000, 100); // Default timeout: 1s, max threads: 100 } public PortScanner(int timeout, int maxThreads) { this.timeout = timeout; this.maxThreads = maxThreads; this.executorService = Executors.newFixedThreadPool(maxThreads); this.completedScans = new AtomicInteger(0); this.openPortsFound = new AtomicInteger(0); this.results = Collections.synchronizedList(new ArrayList<>()); } public List<ScanResult> scan(ScanConfig config) { return scan(config.getHost(), config.getStartPort(), config.getEndPort(), config.getScanType(), config.isServiceDetection()); } public List<ScanResult> scan(String host, int startPort, int endPort, ScanConfig.ScanType scanType, boolean serviceDetection) { resetScanner(); isScanning = true; int totalPorts = endPort - startPort + 1; List<Future<ScanResult>> futures = new ArrayList<>(); System.out.printf("Starting scan of %s, ports %d-%d (%d ports)%n", host, startPort, endPort, totalPorts); for (int port = startPort; port <= endPort; port++) { if (!isScanning) { break; } final int currentPort = port; Future<ScanResult> future = executorService.submit(() -> { if (!isScanning) { return new ScanResult(currentPort, ScanResult.PortStatus.CANCELLED); } ScanResult result = scanPort(host, currentPort, scanType, serviceDetection); completedScans.incrementAndGet(); if (result.getStatus() == ScanResult.PortStatus.OPEN) { openPortsFound.incrementAndGet(); System.out.printf("Found open port: %d (%s)%n", currentPort, result.getService()); } return result; }); futures.add(future); } // Wait for all tasks to complete and collect results for (Future<ScanResult> future : futures) { try { ScanResult result = future.get(); if (result != null) { results.add(result); } } catch (InterruptedException | ExecutionException e) { System.err.println("Error scanning port: " + e.getMessage()); } } isScanning = false; System.out.printf("Scan completed. Found %d open ports.%n", openPortsFound.get()); return getResults(); } private ScanResult scanPort(String host, int port, ScanConfig.ScanType scanType, boolean serviceDetection) { ScanResult result = new ScanResult(port); try { long startTime = System.currentTimeMillis(); switch (scanType) { case TCP_CONNECT: result = tcpConnectScan(host, port); break; case TCP_SYN: result = tcpSynScan(host, port); break; case UDP: result = udpScan(host, port); break; } long endTime = System.currentTimeMillis(); result.setResponseTime(endTime - startTime); // Service detection if (serviceDetection && result.getStatus() == ScanResult.PortStatus.OPEN) { detectService(host, port, result); } } catch (Exception e) { result.setStatus(ScanResult.PortStatus.ERROR); result.setErrorMessage(e.getMessage()); } return result; } private ScanResult tcpConnectScan(String host, int port) { ScanResult result = new ScanResult(port); try (Socket socket = new Socket()) { socket.connect(new InetSocketAddress(host, port), timeout); result.setStatus(ScanResult.PortStatus.OPEN); result.setProtocol("TCP"); } catch (SocketTimeoutException e) { result.setStatus(ScanResult.PortStatus.FILTERED); } catch (ConnectException e) { if (e.getMessage().contains("Connection refused")) { result.setStatus(ScanResult.PortStatus.CLOSED); } else { result.setStatus(ScanResult.PortStatus.ERROR); result.setErrorMessage(e.getMessage()); } } catch (IOException e) { result.setStatus(ScanResult.PortStatus.ERROR); result.setErrorMessage(e.getMessage()); } return result; } private ScanResult tcpSynScan(String host, int port) { // SYN scan requires raw socket access, which Java doesn't provide natively // This is a simplified implementation using TCP connect // For real SYN scanning, you'd need JNI or a native library ScanResult result = new ScanResult(port); result.setStatus(ScanResult.PortStatus.NOT_IMPLEMENTED); result.setErrorMessage("SYN scan requires raw socket access (not available in pure Java)"); return result; } private ScanResult udpScan(String host, int port) { ScanResult result = new ScanResult(port); try (DatagramSocket socket = new DatagramSocket()) { socket.setSoTimeout(timeout); InetAddress address = InetAddress.getByName(host); byte[] sendData = "SCAN".getBytes(); DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, address, port); socket.send(sendPacket); // Try to receive response byte[] receiveData = new byte[1024]; DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); socket.receive(receivePacket); result.setStatus(ScanResult.PortStatus.OPEN); result.setProtocol("UDP"); } catch (SocketTimeoutException e) { // UDP ports often don't respond even when open result.setStatus(ScanResult.PortStatus.OPEN_FILTERED); } catch (IOException e) { if (e.getMessage().contains("Connection refused")) { result.setStatus(ScanResult.PortStatus.CLOSED); } else { result.setStatus(ScanResult.PortStatus.ERROR); result.setErrorMessage(e.getMessage()); } } return result; } private void detectService(String host, int port, ScanResult result) { try (Socket socket = new Socket()) { socket.connect(new InetSocketAddress(host, port), timeout); // Try to read banner socket.setSoTimeout(2000); InputStream input = socket.getInputStream(); OutputStream output = socket.getOutputStream(); String service = guessServiceByPort(port); result.setService(service); // Attempt banner grabbing for common services if (port == 21 || port == 22 || port == 25 || port == 80 || port == 110) { String banner = grabBanner(input, output, port); if (banner != null && !banner.isEmpty()) { result.setBanner(banner); result.setService(service + " - " + banner.split("\n")[0]); } } } catch (Exception e) { // Banner grabbing failed, but port is still open result.setService(guessServiceByPort(port)); } } private String grabBanner(InputStream input, OutputStream output, int port) { try { BufferedReader reader = new BufferedReader(new InputStreamReader(input)); switch (port) { case 21: // FTP return reader.readLine(); case 22: // SSH // SSH sends banner immediately upon connection StringBuilder sshBanner = new StringBuilder(); while (reader.ready()) { sshBanner.append(reader.readLine()).append("\n"); } return sshBanner.toString().trim(); case 25: // SMTP return reader.readLine(); case 80: // HTTP PrintWriter writer = new PrintWriter(output, true); writer.println("HEAD / HTTP/1.0\r\n"); writer.println("User-Agent: PortScanner/1.0\r\n"); writer.println("\r\n"); StringBuilder httpResponse = new StringBuilder(); String line; while ((line = reader.readLine()) != null && !line.isEmpty()) { httpResponse.append(line).append("\n"); } return httpResponse.toString(); case 110: // POP3 return reader.readLine(); } } catch (Exception e) { // Banner grabbing failed silently } return null; } private String guessServiceByPort(int port) { // Common port to service mapping switch (port) { case 21: return "FTP"; case 22: return "SSH"; case 23: return "Telnet"; case 25: return "SMTP"; case 53: return "DNS"; case 80: return "HTTP"; case 110: return "POP3"; case 143: return "IMAP"; case 443: return "HTTPS"; case 993: return "IMAPS"; case 995: return "POP3S"; case 1433: return "MSSQL"; case 1521: return "Oracle"; case 3306: return "MySQL"; case 3389: return "RDP"; case 5432: return "PostgreSQL"; case 5900: return "VNC"; case 6379: return "Redis"; case 27017: return "MongoDB"; default: if (port <= 1024) return "Well-known"; else if (port <= 49151) return "Registered"; else return "Dynamic/Private"; } } public void stopScan() { isScanning = false; executorService.shutdownNow(); System.out.println("Scan stopped by user."); } public boolean isScanning() { return isScanning; } public int getCompletedScans() { return completedScans.get(); } public int getOpenPortsFound() { return openPortsFound.get(); } public List<ScanResult> getResults() { return new ArrayList<>(results); } public List<ScanResult> getOpenPorts() { return results.stream() .filter(r -> r.getStatus() == ScanResult.PortStatus.OPEN) .sorted(Comparator.comparingInt(ScanResult::getPort)) .collect(ArrayList::new, ArrayList::add, ArrayList::addAll); } private void resetScanner() { completedScans.set(0); openPortsFound.set(0); results.clear(); isScanning = false; } public void shutdown() { if (!executorService.isShutdown()) { executorService.shutdown(); try { if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) { executorService.shutdownNow(); } } catch (InterruptedException e) { executorService.shutdownNow(); Thread.currentThread().interrupt(); } } } }

Data Models

package com.portscanner.models; import java.util.Objects; public class ScanResult { private final int port; private PortStatus status; private String service; private String banner; private String protocol; private long responseTime; private String errorMessage; public enum PortStatus { OPEN("Open"), CLOSED("Closed"), FILTERED("Filtered"), OPEN_FILTERED("Open|Filtered"), ERROR("Error"), CANCELLED("Cancelled"), NOT_IMPLEMENTED("Not Implemented"); private final String displayName; PortStatus(String displayName) { this.displayName = displayName; } public String getDisplayName() { return displayName; } @Override public String toString() { return displayName; } } public ScanResult(int port) { this.port = port; this.status = PortStatus.CLOSED; } // Getters and setters public int getPort() { return port; } public PortStatus getStatus() { return status; } public void setStatus(PortStatus status) { this.status = status; } public String getService() { return service; } public void setService(String service) { this.service = service; } public String getBanner() { return banner; } public void setBanner(String banner) { this.banner = banner; } public String getProtocol() { return protocol; } public void setProtocol(String protocol) { this.protocol = protocol; } public long getResponseTime() { return responseTime; } public void setResponseTime(long responseTime) { this.responseTime = responseTime; } public String getErrorMessage() { return errorMessage; } public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ScanResult that = (ScanResult) o; return port == that.port; } @Override public int hashCode() { return Objects.hash(port); } @Override public String toString() { return String.format("Port %d: %s (%s) - %dms", port, status.getDisplayName(), service, responseTime); } }
package com.portscanner.models; public class ScanConfig { private String host; private int startPort; private int endPort; private ScanType scanType; private int timeout; private int maxThreads; private boolean serviceDetection; private boolean bannerGrabbing; public enum ScanType { TCP_CONNECT("TCP Connect"), TCP_SYN("TCP SYN"), UDP("UDP"); private final String displayName; ScanType(String displayName) { this.displayName = displayName; } public String getDisplayName() { return displayName; } @Override public String toString() { return displayName; } } public ScanConfig() { this.host = "localhost"; this.startPort = 1; this.endPort = 1000; this.scanType = ScanType.TCP_CONNECT; this.timeout = 1000; this.maxThreads = 100; this.serviceDetection = true; this.bannerGrabbing = false; } // Getters and setters public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getStartPort() { return startPort; } public void setStartPort(int startPort) { this.startPort = startPort; } public int getEndPort() { return endPort; } public void setEndPort(int endPort) { this.endPort = endPort; } public ScanType getScanType() { return scanType; } public void setScanType(ScanType scanType) { this.scanType = scanType; } public int getTimeout() { return timeout; } public void setTimeout(int timeout) { this.timeout = timeout; } public int getMaxThreads() { return maxThreads; } public void setMaxThreads(int maxThreads) { this.maxThreads = maxThreads; } public boolean isServiceDetection() { return serviceDetection; } public void setServiceDetection(boolean serviceDetection) { this.serviceDetection = serviceDetection; } public boolean isBannerGrabbing() { return bannerGrabbing; } public void setBannerGrabbing(boolean bannerGrabbing) { this.bannerGrabbing = bannerGrabbing; } public void validate() throws IllegalArgumentException { if (host == null || host.trim().isEmpty()) { throw new IllegalArgumentException("Host cannot be empty"); } if (startPort < 1 || startPort > 65535) { throw new IllegalArgumentException("Start port must be between 1 and 65535"); } if (endPort < 1 || endPort > 65535) { throw new IllegalArgumentException("End port must be between 1 and 65535"); } if (startPort > endPort) { throw new IllegalArgumentException("Start port cannot be greater than end port"); } if (timeout < 100) { throw new IllegalArgumentException("Timeout must be at least 100ms"); } if (maxThreads < 1 || maxThreads > 1000) { throw new IllegalArgumentException("Max threads must be between 1 and 1000"); } } @Override public String toString() { return String.format("ScanConfig{host='%s', ports=%d-%d, type=%s, threads=%d}", host, startPort, endPort, scanType, maxThreads); } }

Command Line Interface

package com.portscanner; import com.portscanner.core.PortScanner; import com.portscanner.models.ScanConfig; import com.portscanner.models.ScanResult; import java.util.List; import java.util.Scanner; public class CommandLineScanner { private final PortScanner scanner; private final Scanner inputScanner; public CommandLineScanner() { this.scanner = new PortScanner(); this.inputScanner = new Scanner(System.in); } public void start() { System.out.println("=== Java Port Scanner ==="); System.out.println(); ScanConfig config = getScanConfigFromUser(); try { config.validate(); performScan(config); } catch (IllegalArgumentException e) { System.err.println("Configuration error: " + e.getMessage()); } finally { scanner.shutdown(); inputScanner.close(); } } private ScanConfig getScanConfigFromUser() { ScanConfig config = new ScanConfig(); System.out.print("Enter target host (default: localhost): "); String host = inputScanner.nextLine().trim(); if (!host.isEmpty()) { config.setHost(host); } System.out.print("Enter start port (default: 1): "); String startPortStr = inputScanner.nextLine().trim(); if (!startPortStr.isEmpty()) { config.setStartPort(Integer.parseInt(startPortStr)); } System.out.print("Enter end port (default: 1000): "); String endPortStr = inputScanner.nextLine().trim(); if (!endPortStr.isEmpty()) { config.setEndPort(Integer.parseInt(endPortStr)); } System.out.print("Enable service detection? (y/n, default: y): "); String serviceDetect = inputScanner.nextLine().trim(); if (serviceDetect.equalsIgnoreCase("n")) { config.setServiceDetection(false); } System.out.print("Enter timeout in ms (default: 1000): "); String timeoutStr = inputScanner.nextLine().trim(); if (!timeoutStr.isEmpty()) { config.setTimeout(Integer.parseInt(timeoutStr)); } System.out.print("Enter max threads (default: 100): "); String threadsStr = inputScanner.nextLine().trim(); if (!threadsStr.isEmpty()) { config.setMaxThreads(Integer.parseInt(threadsStr)); } return config; } private void performScan(ScanConfig config) { System.out.println(); System.out.println("Starting scan with configuration:"); System.out.println(" Target: " + config.getHost()); System.out.println(" Ports: " + config.getStartPort() + " - " + config.getEndPort()); System.out.println(" Timeout: " + config.getTimeout() + "ms"); System.out.println(" Threads: " + config.getMaxThreads()); System.out.println(" Service Detection: " + (config.isServiceDetection() ? "Yes" : "No")); System.out.println(); long startTime = System.currentTimeMillis(); // Start a separate thread for progress updates Thread progressThread = new Thread(() -> { while (scanner.isScanning()) { try { Thread.sleep(1000); int completed = scanner.getCompletedScans(); int total = config.getEndPort() - config.getStartPort() + 1; int percent = (int) ((completed / (double) total) * 100); System.out.printf("\rProgress: %d/%d ports (%d%%) - Found: %d open", completed, total, percent, scanner.getOpenPortsFound()); } catch (InterruptedException e) { break; } } }); progressThread.setDaemon(true); progressThread.start(); // Perform the scan List<ScanResult> results = scanner.scan(config); long endTime = System.currentTimeMillis(); long duration = endTime - startTime; System.out.println(); System.out.println(); System.out.println("=== Scan Results ==="); System.out.println("Scan duration: " + duration + "ms"); System.out.println("Total ports scanned: " + results.size()); System.out.println("Open ports found: " + scanner.getOpenPortsFound()); System.out.println(); // Display open ports List<ScanResult> openPorts = scanner.getOpenPorts(); if (openPorts.isEmpty()) { System.out.println("No open ports found."); } else { System.out.println("Open ports:"); System.out.println("Port\tService\tProtocol\tResponse Time"); System.out.println("----\t-------\t--------\t-------------"); for (ScanResult result : openPorts) { System.out.printf("%d\t%s\t%s\t\t%dms%n", result.getPort(), result.getService() != null ? result.getService() : "Unknown", result.getProtocol() != null ? result.getProtocol() : "TCP", result.getResponseTime()); if (result.getBanner() != null && !result.getBanner().isEmpty()) { System.out.println(" Banner: " + result.getBanner().replace("\n", " ")); } } } // Save results option System.out.println(); System.out.print("Save results to file? (y/n): "); String save = inputScanner.nextLine().trim(); if (save.equalsIgnoreCase("y")) { saveResultsToFile(results, config); } } private void saveResultsToFile(List<ScanResult> results, ScanConfig config) { String filename = "portscan_" + config.getHost().replace(".", "_") + "_" + System.currentTimeMillis() + ".txt"; try (java.io.PrintWriter writer = new java.io.PrintWriter(filename)) { writer.println("Port Scan Results"); writer.println("================="); writer.println("Target: " + config.getHost()); writer.println("Port Range: " + config.getStartPort() + " - " + config.getEndPort()); writer.println("Scan Type: " + config.getScanType()); writer.println("Date: " + new java.util.Date()); writer.println(); writer.println("Open Ports:"); writer.println("-----------"); for (ScanResult result : scanner.getOpenPorts()) { writer.printf("%d\t%s\t%s\t%dms%n", result.getPort(), result.getService() != null ? result.getService() : "Unknown", result.getProtocol() != null ? result.getProtocol() : "TCP", result.getResponseTime()); } System.out.println("Results saved to: " + filename); } catch (java.io.IOException e) { System.err.println("Error saving results: " + e.getMessage()); } } public static void main(String[] args) { new CommandLineScanner().start(); } }

Graphical User Interface

package com.portscanner.gui; import com.portscanner.core.PortScanner; import com.portscanner.models.ScanConfig; import com.portscanner.models.ScanResult; import javax.swing.*; import javax.swing.table.DefaultTableModel; import java.awt.*; import java.awt.event.ActionEvent; import java.util.List; import java.util.concurrent.ExecutionException; public class PortScannerGUI extends JFrame { private final PortScanner scanner; private JTextField hostField; private JSpinner startPortSpinner; private JSpinner endPortSpinner; private JComboBox<String> scanTypeComboBox; private JCheckBox serviceDetectionCheckBox; private JSpinner timeoutSpinner; private JSpinner threadsSpinner; private JProgressBar progressBar; private JButton scanButton; private JButton stopButton; private JTable resultsTable; private DefaultTableModel tableModel; private JTextArea logArea; private SwingWorker<List<ScanResult>, ScanResult> scanWorker; public PortScannerGUI() { this.scanner = new PortScanner(); initializeGUI(); } private void initializeGUI() { setTitle("Java Port Scanner"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(900, 700); setLocationRelativeTo(null); // Create main panel JPanel mainPanel = new JPanel(new BorderLayout(10, 10)); mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); // Configuration panel mainPanel.add(createConfigPanel(), BorderLayout.NORTH); // Results panel mainPanel.add(createResultsPanel(), BorderLayout.CENTER); // Log panel mainPanel.add(createLogPanel(), BorderLayout.SOUTH); add(mainPanel); } private JPanel createConfigPanel() { JPanel panel = new JPanel(new GridLayout(0, 2, 5, 5)); panel.setBorder(BorderFactory.createTitledBorder("Scan Configuration")); // Host panel.add(new JLabel("Target Host:")); hostField = new JTextField("localhost"); panel.add(hostField); // Port range panel.add(new JLabel("Start Port:")); startPortSpinner = new JSpinner(new SpinnerNumberModel(1, 1, 65535, 1)); panel.add(startPortSpinner); panel.add(new JLabel("End Port:")); endPortSpinner = new JSpinner(new SpinnerNumberModel(1000, 1, 65535, 1)); panel.add(endPortSpinner); // Scan type panel.add(new JLabel("Scan Type:")); scanTypeComboBox = new JComboBox<>(new String[]{"TCP Connect", "TCP SYN", "UDP"}); panel.add(scanTypeComboBox); // Service detection panel.add(new JLabel("Service Detection:")); serviceDetectionCheckBox = new JCheckBox("", true); panel.add(serviceDetectionCheckBox); // Timeout panel.add(new JLabel("Timeout (ms):")); timeoutSpinner = new JSpinner(new SpinnerNumberModel(1000, 100, 10000, 100)); panel.add(timeoutSpinner); // Threads panel.add(new JLabel("Max Threads:")); threadsSpinner = new JSpinner(new SpinnerNumberModel(100, 1, 500, 10)); panel.add(threadsSpinner); // Buttons JPanel buttonPanel = new JPanel(new FlowLayout()); scanButton = new JButton("Start Scan"); stopButton = new JButton("Stop Scan"); stopButton.setEnabled(false); scanButton.addActionListener(this::startScan); stopButton.addActionListener(this::stopScan); buttonPanel.add(scanButton); buttonPanel.add(stopButton); JPanel container = new JPanel(new BorderLayout()); container.add(panel, BorderLayout.CENTER); container.add(buttonPanel, BorderLayout.SOUTH); return container; } private JPanel createResultsPanel() { JPanel panel = new JPanel(new BorderLayout()); panel.setBorder(BorderFactory.createTitledBorder("Scan Results")); // Table String[] columnNames = {"Port", "Status", "Service", "Protocol", "Response Time", "Banner"}; tableModel = new DefaultTableModel(columnNames, 0) { @Override public boolean isCellEditable(int row, int column) { return false; } }; resultsTable = new JTable(tableModel); resultsTable.setAutoCreateRowSorter(true); JScrollPane scrollPane = new JScrollPane(resultsTable); // Progress bar progressBar = new JProgressBar(); progressBar.setStringPainted(true); panel.add(progressBar, BorderLayout.NORTH); panel.add(scrollPane, BorderLayout.CENTER); return panel; } private JPanel createLogPanel() { JPanel panel = new JPanel(new BorderLayout()); panel.setBorder(BorderFactory.createTitledBorder("Scan Log")); panel.setPreferredSize(new Dimension(0, 150)); logArea = new JTextArea(); logArea.setEditable(false); logArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); JScrollPane scrollPane = new JScrollPane(logArea); panel.add(scrollPane, BorderLayout.CENTER); return panel; } private void startScan(ActionEvent e) { ScanConfig config = createConfigFromUI(); try { config.validate(); startScanWorker(config); } catch (IllegalArgumentException ex) { JOptionPane.showMessageDialog(this, ex.getMessage(), "Configuration Error", JOptionPane.ERROR_MESSAGE); } } private ScanConfig createConfigFromUI() { ScanConfig config = new ScanConfig(); config.setHost(hostField.getText().trim()); config.setStartPort((Integer) startPortSpinner.getValue()); config.setEndPort((Integer) endPortSpinner.getValue()); config.setScanType(ScanConfig.ScanType.TCP_CONNECT); // Default config.setServiceDetection(serviceDetectionCheckBox.isSelected()); config.setTimeout((Integer) timeoutSpinner.getValue()); config.setMaxThreads((Integer) threadsSpinner.getValue()); return config; } private void startScanWorker(ScanConfig config) { scanWorker = new SwingWorker<List<ScanResult>, ScanResult>() { @Override protected List<ScanResult> doInBackground() throws Exception { log("Starting scan: " + config); return scanner.scan(config); } @Override protected void process(List<ScanResult> chunks) { for (ScanResult result : chunks) { if (result.getStatus() == ScanResult.PortStatus.OPEN) { addResultToTable(result); log("Open port found: " + result.getPort() + " (" + result.getService() + ")"); } } // Update progress int total = config.getEndPort() - config.getStartPort() + 1; int completed = scanner.getCompletedScans(); int percent = (int) ((completed / (double) total) * 100); progressBar.setValue(percent); progressBar.setString(String.format("%d/%d ports (%d%%) - %d open", completed, total, percent, scanner.getOpenPortsFound())); } @Override protected void done() { scanButton.setEnabled(true); stopButton.setEnabled(false); progressBar.setValue(100); try { List<ScanResult> results = get(); log("Scan completed. Found " + scanner.getOpenPortsFound() + " open ports."); // Show summary JOptionPane.showMessageDialog(PortScannerGUI.this, String.format("Scan completed!\n\n" + "Target: %s\n" + "Ports scanned: %d\n" + "Open ports found: %d", config.getHost(), results.size(), scanner.getOpenPortsFound()), "Scan Complete", JOptionPane.INFORMATION_MESSAGE); } catch (InterruptedException | ExecutionException ex) { log("Scan failed: " + ex.getMessage()); JOptionPane.showMessageDialog(PortScannerGUI.this, "Scan failed: " + ex.getMessage(), "Scan Error", JOptionPane.ERROR_MESSAGE); } } }; // Clear previous results tableModel.setRowCount(0); logArea.setText(""); // Update UI state scanButton.setEnabled(false); stopButton.setEnabled(true); progressBar.setValue(0); scanWorker.execute(); } private void stopScan(ActionEvent e) { if (scanWorker != null && !scanWorker.isDone()) { scanner.stopScan(); scanWorker.cancel(true); log("Scan stopped by user."); } scanButton.setEnabled(true); stopButton.setEnabled(false); } private void addResultToTable(ScanResult result) { Object[] row = { result.getPort(), result.getStatus().getDisplayName(), result.getService(), result.getProtocol(), result.getResponseTime() + "ms", result.getBanner() }; tableModel.addRow(row); } private void log(String message) { SwingUtilities.invokeLater(() -> { logArea.append("[" + java.time.LocalTime.now() + "] " + message + "\n"); logArea.setCaretPosition(logArea.getDocument().getLength()); }); } @Override public void dispose() { scanner.shutdown(); super.dispose(); } public static void main(String[] args) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeel()); } catch (Exception e) { e.printStackTrace(); } SwingUtilities.invokeLater(() -> { new PortScannerGUI().setVisible(true); }); } }

Advanced Features

Service Detection Database

package com.portscanner.utils; import java.util.HashMap; import java.util.Map; public class ServiceDatabase { private static final Map<Integer, String> PORT_SERVICES = new HashMap<>(); static { // Well-known ports PORT_SERVICES.put(7, "Echo"); PORT_SERVICES.put(20, "FTP Data"); PORT_SERVICES.put(21, "FTP Control"); PORT_SERVICES.put(22, "SSH"); PORT_SERVICES.put(23, "Telnet"); PORT_SERVICES.put(25, "SMTP"); PORT_SERVICES.put(53, "DNS"); PORT_SERVICES.put(67, "DHCP Server"); PORT_SERVICES.put(68, "DHCP Client"); PORT_SERVICES.put(69, "TFTP"); PORT_SERVICES.put(80, "HTTP"); PORT_SERVICES.put(110, "POP3"); PORT_SERVICES.put(123, "NTP"); PORT_SERVICES.put(143, "IMAP"); PORT_SERVICES.put(161, "SNMP"); PORT_SERVICES.put(162, "SNMP Trap"); PORT_SERVICES.put(443, "HTTPS"); PORT_SERVICES.put(465, "SMTPS"); PORT_SERVICES.put(587, "SMTP Submission"); PORT_SERVICES.put(993, "IMAPS"); PORT_SERVICES.put(995, "POP3S"); // Database services PORT_SERVICES.put(1433, "MSSQL"); PORT_SERVICES.put(1521, "Oracle"); PORT_SERVICES.put(3306, "MySQL"); PORT_SERVICES.put(5432, "PostgreSQL"); PORT_SERVICES.put(27017, "MongoDB"); PORT_SERVICES.put(6379, "Redis"); // Remote access PORT_SERVICES.put(3389, "RDP"); PORT_SERVICES.put(5900, "VNC"); // File sharing PORT_SERVICES.put(2049, "NFS"); PORT_SERVICES.put(445, "SMB"); // Messaging PORT_SERVICES.put(5222, "XMPP"); PORT_SERVICES.put(5269, "XMPP Server"); } public static String getService(int port) { return PORT_SERVICES.getOrDefault(port, "Unknown"); } public static boolean isWellKnownPort(int port) { return port <= 1024; } public static boolean isRegisteredPort(int port) { return port > 1024 && port <= 49151; } public static boolean isDynamicPort(int port) { return port > 49151; } }

Usage Examples

Basic Scanning

// Simple port scan PortScanner scanner = new PortScanner(); List<ScanResult> results = scanner.scan("localhost", 1, 1000, ScanConfig.ScanType.TCP_CONNECT, true); // Print open ports for (ScanResult result : scanner.getOpenPorts()) { System.out.println(result); }

Advanced Configuration

// Custom configuration ScanConfig config = new ScanConfig(); config.setHost("192.168.1.1"); config.setStartPort(20); config.setEndPort(443); config.setTimeout(2000); config.setMaxThreads(50); config.setServiceDetection(true); PortScanner scanner = new PortScanner(config.getTimeout(), config.getMaxThreads()); List<ScanResult> results = scanner.scan(config);

Key Features

  1. Multi-threaded Scanning - Fast parallel port scanning
  2. Multiple Scan Types - TCP Connect, SYN (theoretical), UDP
  3. Service Detection - Automatic service identification
  4. Banner Grabbing - Retrieve service banners
  5. Progress Tracking - Real-time progress updates
  6. Results Export - Save scan results to file
  7. User-friendly Interfaces - Both CLI and GUI versions
  8. Configurable Parameters - Timeout, threads, port ranges

Security Notes

  • Always ensure you have permission to scan target systems
  • Port scanning may be considered intrusive or illegal in some contexts
  • Use responsibly and ethically
  • Some networks may have intrusion detection systems that will detect port scans

This port scanner provides a comprehensive tool for network analysis and security testing with professional-grade features and user interfaces.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper