Python Port Scanner
This utility scans a target IP address or hostname for open ports. It uses the socket module to attempt connections and threading to scan multiple ports simultaneously for performance.
Modules Used:
- socket: To create network connections and check ports.
threading: To run multiple scan attempts concurrently.queue: To manage the list of ports to be scanned in a thread-safe way.- argparse: To handle command-line arguments.
The Code
Save this as port_scanner.py.
import socket
import threading
import queue
import argparse
from datetime import datetime
# Thread-safe print lock to prevent garbled output
print_lock = threading.Lock()
def scan_port(target, port):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(1) # Timeout for connection attempt
# connect_ex returns 0 if connection is successful, error code otherwise
result = s.connect_ex((target, port))
if result == 0:
with print_lock:
print(f"Port {port}: OPEN")
s.close()
except Exception:
pass
def worker(target, q):
while True:
port = q.get()
scan_port(target, port)
q.task_done()
def main(target, start_port, end_port, thread_count):
print(f"Scanning target: {target}")
print(f"Scanning ports: {start_port}-{end_port}")
print(f"Time started: {datetime.now()}")
print("-" * 50)
q = queue.Queue()
# Create threads
for _ in range(thread_count):
t = threading.Thread(target=worker, args=(target, q))
t.daemon = True # Daemon threads exit when main program exits
t.start()
# Fill queue with ports
for port in range(start_port, end_port + 1):
q.put(port)
# Wait for queue to be empty
q.join()
print("-" * 50)
print("Scanning completed")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Multi-threaded Port Scanner")
parser.add_argument("target", help="Target IP or Hostname")
parser.add_argument("--start", type=int, default=1, help="Start Port (default: 1)")
parser.add_argument("--end", type=int, default=1024, help="End Port (default: 1024)")
parser.add_argument("--threads", type=int, default=100, help="Number of threads (default: 100)")
args = parser.parse_args()
# Resolve hostname to IP
try:
target_ip = socket.gethostbyname(args.target)
except socket.gaierror:
print("Hostname could not be resolved.")
exit()
main(target_ip, args.start, args.end, args.threads)
Usage
# Scan common ports (1-1024) on localhost
python port_scanner.py localhost
# Scan a specific range on a server
python port_scanner.py 192.168.1.1 --start 80 --end 8080 --threads 200