Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

Java Top

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

> CHECK OUT THE COURSE

1. Overview

Port scanning with Java is a method of enumerating the open or active ports of a target machine. The goal is mainly to list the open ports in order to know the applications and services that are currently running.

In this tutorial, we'll explain how to develop a simple application for port scanning with Java that we can use to scan a host for open ports.

2. What Is a Computer Port?

A computer port is a logical entity that makes it possible to associate a particular service with a connection. Furthermore, a port is identified by an integer from 1 to 65535. By convention, the first 1024 are reserved for standard services such as:

  • Port 20: FTP
  • Port 23: Telnet
  • Port 25: SMTP
  • Port 80: HTTP

The idea of a port scanner is to create a TCP Socket and try to connect to a specific port. If the connection is successfully established, then we'll mark this port as open, and if not, we'll mark it as closed.

However, establishing a connection on each of the 65535 ports can take up to 200 ms per port. This may sound like a short amount of time, but in total, it would take a considerable amount of time to scan all ports of a single host one by one.

To solve the performance issue, we'll use the multi-threaded approach. This can dramatically speed up the process compared to attempting to connect to each port sequentially.

3. Implementation

To implement our program, we create a function portScan() with two parameters as input:

  • ip: the IP address to scan; it's equivalent to 127.0.0.1 for localhost
  • nbrPortMaxToScan: the maximal number of ports to scan; this number is equivalent to 65535 if we want to scan all ports

3.1 Implementation

Let's see what our portScan() method looks like:

public void runPortScan(String ip, int nbrPortMaxToScan) throws IOException {
        ConcurrentLinkedQueue openPorts = new ConcurrentLinkedQueue<>();
        ExecutorService executorService = Executors.newFixedThreadPool(poolSize);
        AtomicInteger port = new AtomicInteger(0);
        while (port.get() < nbrPortMaxToScan) {
                final int currentPort = port.getAndIncrement();
                executorService.submit(() -> {
                        try {
                                Socket socket = new Socket();
                                socket.connect(new InetSocketAddress(ip, currentPort), timeOut);
                                socket.close();
                                openPorts.add(currentPort);
                                System.out.println(ip + " ,port open: " + currentPort);
                        } catch (IOException e) {
                                System.err.println(e);
                        }
                });
        }
        executorService.shutdown();
        try {
                executorService.awaitTermination(10, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
                throw new RuntimeException(e);
        }
        List openPortList = new ArrayList<>();
        System.out.println("openPortsQueue: " + openPorts.size());
        while (!openPorts.isEmpty()) {
                openPortList.add(openPorts.poll());
        }
        openPortList.forEach(p -> System.out.println("port " + p + " is open"));
}

Our method returns a List with all open ports. To do so, we create a new Socket object to be used as a connector between two hosts. If a connection is successfully established, then we assume that the port is open, in which case we continue to the next line. On the other hand, if the connection fails, then we assume that the port is closed and a SocketTimeoutException is thrown and we are thrown to the exception catch block.

3.2 Multithreading

In order to optimize the amount of time needed to scan all 65535 Ports of the target machine, we'll run our method concurrently. We use the ExecutorService, which encapsulates a pool of threads and a queue of tasks to be executed. All threads in the pool are still running.

The service checks if a task is to be processed in the queue and, if so, it withdraws the task and executes it. Once the task is executed, the thread waits again for the service to assign it a new task from the queue.

Furthermore, we use a FixedThreadPool with 10 Threads, which means that the program is going to run up to a maximum of 10 threads in parallel. We can adjust this pool size according to our machine configuration and capacities.

4. Conclusion

In this quick tutorial, we explained how to develop a simple application for port scanning with Java using Sockets and a multi-threaded approach.

As always, the code snippets are available over on GitHub.

Java bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> CHECK OUT THE COURSE
Generic footer banner
Comments are closed on this article!