0

Noob here trying to learn how to make a port scanner in Java. I want the code to take all consecutive closed ports and print on one line that they are closed, like "ports 1000 to 4000 are closed". Here is my code so far:

import java.net.*;
public class KalebPortScanner {

    public static void main(String[] args) {
        String host = "localhost"; // replace localhost with IP of device to scan from

        int startingPort = 0; 
        int endingPort = 65535;
        
        for (int port=startingPort;port<=endingPort;port++) {   
        
            try {
            Socket socket = new Socket();
            socket.connect(new InetSocketAddress(host, port),100);
            System.out.println(+port+ " open");
            socket.close();
        int goodPort = port;
        } catch (Exception e) {
            // TODO: if port is closed
            int badPort = port;
            //System.out.println(+badPort+ " to " +port+ " are closed");
            //System.out.println(+port+ " closed");
        }
        }

    }

}

It's basically a mess but I'm trying to understand how I can mark "badPort" as the lower of the closed ports and "goodPort" as the highest one, and then print it. I appreciate all advice for cleaning this up or ways to improve it. Thank you!

Tried making a variable "goodPort" which equals "port" as long as the port is open, and "badPort" which sets itself to "port" if it's closed, and then tries to put them in one System.out.println to give the user the range of closed ports.

ndc85430
  • 1,395
  • 3
  • 11
  • 17
Klob
  • 3
  • 2
  • 1
    One idea is to split your application into smaller, easier to code tasks. Create a `PortTest` getter/setter class that holds a port number and a status. Scan your ports, creating a `PortTest` instance for each port tested. Save these `PortTest` instances in a `java.util.List`. After you've scanned all the ports, read your `List` and condense the good and bad ports into ranges, which you output. Empty the `List` and start over. – Gilbert Le Blanc May 29 '23 at 21:59
  • You say you want to print a range but then you want to print one good and one bad. You have to be clear on what you need. – aled May 29 '23 at 22:28
  • What I was trying to do was take the first bad or closed port, and then the most recent good port and then use those to make my range of closed ports. It would be like bad port to good port-1 are closed. Sorry for the confusion. I like your recommendation, Gilbert, and I'll give it a shot when I get home. For now I'm just happy the initial program works. – Klob May 29 '23 at 22:35
  • a more native idea: start a (OS) netstat/ss/lsof "process" from java... [win](https://stackoverflow.com/q/48198/592355), [x-like](https://www.cyberciti.biz/faq/how-to-check-open-ports-in-linux-using-the-cli/) – xerx593 May 30 '23 at 10:44
  • "algorithmically" the problem is: your variables are useless/dead store! :) try a `List goodPorts` (and "badPorts" accordingly) ...it must not be a list, but anything what can "store" you ~65k "booleans" (e.g. (boolean[65535]..) – xerx593 May 30 '23 at 10:54

1 Answers1

0

I think you can create a class to hold the port range and state:

public class PortRange {
    public int min;
    public int max;

    public final boolean isPortBusy;

    public PortRange(int minPort, boolean isPortBusy) {
        this.min = minPort;
        this.max = minPort;
        this.isPortBusy = isPortBusy;
    }
}

Then do something like this in main method:

List<PortRange> portRanges = new LinkedList<>();
PortRange portRange = null;

for (int port = 0; port < 65536; port++) {
    boolean isPortBusy = isPortBusy(port);

    if (portRange == null) {
        portRange = new PortRange(port, isPortBusy);
    } else if (portRange.isPortBusy == isPortBusy) {
        portRange.max = port;
    } else {
        portRanges.add(portRange);
        portRange = new PortRange(port, isPortBusy);
    }
}

portRanges.add(portRange);

In this code, the static method isPortBusy(port) returns true or false depending on whether the port is busy or not.

Then iterate through the collection and display the result:

portRanges.forEach(range -> System.out.printf("Port range %d-%d : %s%n", range.min, range.max, (range.isPortBusy ? "Busy" : "Free")));

Example of output:

enter image description here

Shadow4571
  • 382
  • 2
  • 4
  • 10