I'm trying to make a module that scans a given IP address and returns true or false for each port depending on it's current state. It works fine when the context manager is called by itself but when it's called within a function it stops using all of it's allocated threads. Here is my code:
import socket
import concurrent.futures
def _scan(ip, port):
scanner = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
scanner.settimeout(1)
try:
scanner.connect((ip, port))
scanner.close()
return True
except:
return False
def portScan(ip, workers, portNum):
with concurrent.futures.ThreadPoolExecutor(max_workers=workers) as executor:
for port in range(portNum):
future = executor.submit(_scan, ip, port + 1)
print(future.result())
portScan("1.1.1.1", 100, 1000)
The problem is that you are waiting for each future to complete before submitting the next. You could use map
instead. It will fan out the work to all of the threads and iterate the results in the same order as the parameters submitted.
import socket
import concurrent.futures
def _scan(params):
ip, port = params
scanner = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
scanner.settimeout(1)
try:
scanner.connect((ip, port))
scanner.close()
return True
except:
return False
def portScan(ip, workers, portNum):
with concurrent.futures.ThreadPoolExecutor(max_workers=workers) as executor:
for result in executor.map(_scan, ((ip, port) for port in range(portNum))):
print(result)
portScan("127.0.0.1", 5, 22)