Home > Blockchain >  Multiple threads for port scanning?
Multiple threads for port scanning?

Time:01-19

I wrote the following small script in python which scans for open tcp ports but it runs slow, I want to improve performance by using threads, how can I implement such feature?

socket.setdefaulttimeout(0.01)
    for port in range(0, 65536):
        s = None
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if s.connect_ex((sys.argv[1], port)) == 0:
            open_ports.append(port)
        s.close()

I would like to set the number of threads via a variable.

CodePudding user response:

Since the python is one of the "slowest" languages and the operation that you'd like to perform is simple, i'd suggest you to use c lang or any other mid-low level languages.
Multithreading to increase speed in a naturally slow language is just a futile effort, my opinion.

There're tons of examples online I'd suggest you to check https://codereview.stackexchange.com/questions/85553/simple-c-port-scanner

CodePudding user response:

I'd write something like:

import socket
from multiprocessing.pool import ThreadPool

def check_socket(host, port):
    socket.setdefaulttimeout(0.01)
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        # return port if open, None otherwise
        return port if s.connect_ex((host, port)) == 0 else None


def main(host):
    with ThreadPool() as pool:
        result = pool.starmap(check_socket, ((host, port) for port in range(0, 65536)))
        # Pull out the list of open ports
        return [x for x in result if x is not None]

CodePudding user response:

Put your code in a function start_scan(port_range)

And Check the asyncio library:

asyncio.create_task(start_scan(port_range))

Then you can have a loop for the number of threads you want, and you create as much task as you want. Then you await them one per one, or gather them.

See https://docs.python.org/3/library/asyncio-task.html

======= EDIT =======
To answer the question, how to split the range in sub list:

import math

def split_ports(ports, threads):
    ports_per_threads = [[]]
    n_port_per_thread = math.ceil(len(ports)/threads)

    i = 0
    t = 0
    for p in ports:
        i =1
        if (i > n_port_per_thread):
            i = 0
            t  = 1
            ports_per_threads.append(list())
        ports_per_threads[t].append(p)

ports = range(100, 200)
ports_lists = split_ports(ports, 4)

That would give you this result :

ports = range(1, 9)
ports_lists = split_ports(ports, 4)
# -> [[1, 2], [3, 4], [5, 6], [7, 8]]
ports_lists = split_ports(ports, 2)
# -> [[1, 2, 3, 4], [5, 6, 7, 8]]
  •  Tags:  
  • Related