On Jun 26, 2026 11:31 PM, yodabytz wrote:
> Take this simple port scanner, and make it better.
>
> import socket import sys
> host = sys.argv[1] if len(sys.argv) > 1 else input("Host: ")
> print(f"Scanning {host}...\n")
> for port in range(1, 1025): s = socket.socket(socket.AF_INET,
> socket.SOCK_STREAM) s.settimeout(0.2)
> if s.connect_ex((host, port)) == 0: try: service = socket.getservbyport(port)
> except: service = "unknown" print(f"{port:5d}/tcp OPEN ({service})")
> s.close()
> print("\nDone.") ```
> Note: If you build a longer version, paste your code into a pastebin or
> similar code-sharing page and leave the link in your reply. That keeps the
> thread readable while still letting everyone review the code.
I’d probably start by making it multithreaded since scanning each port one by one is gonna be pretty slow. I’d also add argparse for things like custom port ranges, timeout, and number of threads, plus some better error handling. Something like this:
#!/usr/bin/env python3
import argparse
import socket
from concurrent.futures import ThreadPoolExecutor, as_completed
def scan_port(host, port, timeout):
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.settimeout(timeout)
if s.connect_ex((host, port)) == 0:
try:
service = socket.getservbyport(port, "tcp")
except OSError:
service = "unknown"
return port, service
except OSError:
pass
return None
def main():
parser = argparse.ArgumentParser()
parser.add_argument("host")
parser.add_argument("-p", "--ports", default="1-1024")
parser.add_argument("-t", "--timeout", type=float, default=0.2)
parser.add_argument("-w", "--workers", type=int, default=50)
args = parser.parse_args()
try:
if "-" in args.ports:
start, end = map(int, args.ports.split("-", 1))
ports = range(start, end + 1)
else:
ports = [int(p) for p in args.ports.split(",")]
ip = socket.gethostbyname(args.host)
except (ValueError, socket.gaierror) as e:
print(f"Error: {e}")
return
print(f"Scanning {args.host} ({ip})...\n")
with ThreadPoolExecutor(max_workers=args.workers) as executor:
futures = [
executor.submit(scan_port, ip, port, args.timeout)
for port in ports
]
for future in as_completed(futures):
result = future.result()
if result:
port, service = result
print(f"{port:5}/tcp OPEN ({service})")
if __name__ == "__main__":
main()
Then you could add stuff like banner grabbing, UDP scanning, IPv6 support, and maybe CIDR ranges later. But I’d probably keep it simple for now, otherwise it starts turning into a whole different project lol.