Ronnie Atuhaire
Ronnie Atuhaire's Blog

Ronnie Atuhaire's Blog

Python Port Scanning With Threads

Python Port Scanning With Threads

Ronnie Atuhaire's photo
Ronnie Atuhaire
Jul 30, 2022

5 min read

Subscribe to my newsletter and never miss my upcoming articles

Table of contents

  • Just a recap, what are ports?
  • Most Exploited Ports
  • Code
  • Conclusion

Port scanning is part of the first phase of a penetration test and allows you to find all network entry points available on a target system. I have a full introductory article about this subject and you may want to check it out before you proceed.

Just a recap, what are ports?

A port is a virtual array used by computers to communicate with other computers over a network. A port is also referred to as the number assigned to a specific network protocol. A network protocol is a set of rules that determine how devices transmit data to and fro on a network.

The two most common types of network protocols are the Transmission Control Protocol (TCP) and the User Datagram Protocol (UDP).


As I mentioned in the blog I first wrote, scanning ports is an important part of penetration testing. It allows you to identify and exploit vulnerabilities in websites, mobile applications, or systems.

Most Exploited Ports


Port 22 is subject to countless, unauthorized login attempts by hackers who are attempting to access unsecured servers. A highly effective deterrent is to simply turn off Port 22 and run the service on a seemingly random port above 1024 (and up to 65535).

20 & 21

Ports 20 and 21 are solely TCP ports used to allow users to send and receive files from a server to their personal computers. FTP stands for File Transfer Protocol. The FTP port is insecure and outdated and can be exploited


The Telnet protocol is a TCP protocol that enables a user to connect to remote computers over the internet. The Telnet port has long been replaced by SSH, but it is still used by some websites today. It is outdated, insecure, and vulnerable to malware. Telnet is vulnerable to spoofing, credential sniffing, and credential brute-forcing.

Obviously there are more ports than this lie Port 69(TFTP), HTTP / HTTPS (443, 80, 8080, 8443), SMB (139, 137, 445).

So let's code a faster solution for port scanning because you may want to test your home router or network and patch yourself as early as possible.

I will be using the following libraries;

The argparse module makes it easy to write user-friendly command-line interfaces.

Python's standard library consists of various built-in modules that support interprocess communication and networking.

This has the upshot of providing a simple cross-platform API for printing coloured terminal text

To create a multi-threaded application since it will involve waiting.

The queue module implements multi-producer and multi-consumer queues. It is especially useful in threaded programming when information must be exchanged safely


import argparse
import socket # for connecting
from colorama import init, Fore

from threading import Thread, Lock
from queue import Queue

Now let's add some colours

Let's create a number of threads we shall have in our application to have a faster search/scan. You can edit this.

Also, let's initialise a queue!

# thread queue
q = Queue()
print_lock = Lock()

In multithreading when multiple threads are working simultaneously on a shared resource like a file(reading and writing data into a file), then to avoid concurrent modification error(multiple threads accessing the same resource leading to inconsistent data) some sort of locking mechanism is used.

Now, let's create our scanning function using basic socket methods.

def port_scan(port):
    Scan a port on the global variable `host`
        s = socket.socket()
        s.connect((host, port))
        with print_lock:
            print(f"{GRAY}{host:15}:{port:5} is closed  {RESET}", end='\r')
        with print_lock:
            print(f"{GREEN}{host:15}:{port:5} is open    {RESET}")

This is going to be our scanning thread method that will assist us on the particular threads at hand and it will call the above function. Refer to comments for more explanation.

def scan_thread():
    global q
    while True:
        # get the port number from the queue
        worker = q.get()
        # scan that port number
        # tells the queue that the scanning for that port
        # is done

Finally, we create our main method; Please consider my comments for code explanation.

def main(host, ports):
    global q
    for t in range(N_THREADS):
        # for each thread, start it
        t = Thread(target=scan_thread)
        # when we set daemon to true, that thread will end when the main thread ends
        t.daemon = True
        # start the daemon thread

    for worker in ports:
        # for each port, put that port into the queue
        # to start scanning

    # wait the threads ( port scanners ) to finish

Now, let's test our script;

if __name__ == "__main__":
    # parse some parameters passed
    parser = argparse.ArgumentParser(description="Simple port scanner")
    parser.add_argument("host", help="Host to scan.")
    parser.add_argument("--ports", "-p", dest="port_range", default="1-65535", help="Port range to scan, default is 1-65535 (all ports)")
    args = parser.parse_args()
    host, port_range =, args.port_range

    start_port, end_port = port_range.split("-")
    start_port, end_port = int(start_port), int(end_port)

    ports = [ p for p in range(start_port, end_port)]

    main(host, ports)

To run the above script, you will have to add an argument in the command line for the target IP. This could be your default gateway IP, home router etc.



The above will search for the 65535 default ports. But if you wish to specify, you can do something like this;

py --ports 1-1024

For example, on my side; I have an output like this;


For the full code, visit repo.


Once again, hope you learned something today from my little closet.

Please consider subscribing or following me for related content, especially about Tech, Python & General Programming.


You can show extra love by buying me a coffee to support this free content and I am also open to partnerships, technical writing roles, collaborations and Python-related training or roles.

Buy Ronnie A Coffee

You can also follow me on Twitter : Waiting for you!

Share this