Programmers T-shirts

Create a Multi Threaded Port Scanner with Java

Updated: Mar 1, 2021

In this tutorial, we will explain how to create a Port Scanner with Java.

Warning - It is illegal to scan someone's network without his or her permission. Such an action is considered an attack. You are however allowed to scan your own private network.




What is a Port Scanner?

A Port Scanner is a tool that scans an IP in the local network by trying to access all ports of that machine.

It creates a new TCP socket and tries to connect to a specific port.

If the connection is established - this port is marked as open, if not - it is marked as closed. We repeat the same process for a range of ports.

Every machine has a potential 65535 available ports while trying to establish a connection on each one of them can take up to 200 ms.

This may sound like a short amount of time, but in total, it takes a very long to scan all ports of a single machine.

We then have to multiply that amount by the number of machines in the network.

In order to provide sufficient performance, this Port Scanner is going to run in parallel - using the ExecutorService interface in Java.


What are Port Scanners used for?

  1. Security - you might want to know which ports on your network are open, since every open port is a potential vulnerability in the system.

  2. There are many Network Monitor tools out there that use Port Scanners under the hood.

  3. Application usage - your application might need to be connected to different machines over TCP. For that, it needs to know which ports are available.


The Code


Code Explanation

Let's examine the portScanner() method.

The method gets an IP as an input and returns a List with all open ports.


The Core Logic

We create a new Socket. This object is used to create a connection between 2 machines.

The connect() method gets an InetSocketAddress object, which is an IP-Port implementation for the abstract SocketAddress class, and a timeout for the connection - 200 ms is typical.

At this point we expect 2 scenarios:

  1. Connection established, we continue to next line - meaning the port is open

  2. Connection failed, SocketTimeoutException is thrown and we are being thrown to IOExecption catch block - meaning the port is close.

Concurrent Run

In order to have a reasonable runtime, we will run this logic concurrently.

We use the ExecutorService interface along with the Executors Factory class which provides simple and easy to use implementations.

We will use a FixedThreadPool with 50 Threads - meaning the program is going to run in a parallelism of 50.

You can tweak this parameter depends on the HW you are using.

ExecutorService executorService = Executors.newFixedThreadPool(50);


The logic is running over all 65535 Ports of the target machine, for each iteration it calls the

executorService.submit(() -> { });

Note that the curly braces get a Runnable object - here it runs the core logic of the Port Scanner.

Since it runs in parallel, open ports cannot be added to a regular list - it needs to use a Thread Safe List in order to avoid race conditions.

We chose to use ConcurrentLinkedQueue to hold all open ports, and AtomicInteger to track the current port I'm testing.


Synchronization - in order to make the portScan() method synchronized, the concurrent block needs to wait for the Runnable task to be returned.

We achieved that by adding the executorService.shutdown() method at the end.


The Return Statement

At the end of the portScan() method, the ConcurrentLinkedQueue is being converted to a simple List. This part is optional, but I've found it simpler to return a List which is a typical data structure than a Concurrent Queue.


The complete project can be found here


Practical Programming Tutorials for Developers

Work Desk

The SW Developer

The SW Developer was built in order to provide Practical and Simple Tutorials for programmers.

Created by Dotan Raz, Michael Rodov & Kobi Atiya

  • github
  • LinkedIn

Subscribe

Programmers T-shirts