A beginner-friendly TCP/UDP port scanner built in Python.
This project was built step-by-step to learn:
- socket programming
- command-line interfaces (
argparse) - multithreading (
ThreadPoolExecutor) - JSON output
- basic testing with
unittest
Use this tool only on systems you own or have explicit permission to test. Unauthorized scanning may be illegal.
- TCP scanning (
--scan-type tcp) - UDP scanning (
--scan-type udp) - Port range scanning (
--start,--end) - Multithreaded scanning (
--threads) - Optional TCP banner grabbing (
--banner) - JSON result export (
--output) - Input validation for safe argument ranges
- Automated tests
port_scanner.py: Entry point and orchestrationcli.py: Command-line argument definitionsscanner.py: TCP/UDP scanning logicutils.py: Validation and JSON save helperstests/test_validation.py: Validation unit teststests/test_scanner.py: Local integration-style scanner tests
- Python 3.10+
- Works on Windows PowerShell (also compatible with other shells)
Open terminal in project folder and run:
python port_scanner.py 127.0.0.1 --start 1 --end 1024target(required): Domain or IP--scan-type {tcp,udp}: Protocol to scan (default:tcp)--start: Start port (default:1)--end: End port (default:1024)--timeout: Socket timeout in seconds (default:0.5)--threads: Number of threads (default:100, allowed:1-500)--banner: Try banner grabbing for open TCP ports--output: Output JSON path (default:result.json)
python port_scanner.py 127.0.0.1 --scan-type tcp --start 1 --end 1024python port_scanner.py 127.0.0.1 --scan-type tcp --start 8000 --end 8005 --banner --output result_tcp.jsonpython port_scanner.py 127.0.0.1 --scan-type udp --start 53 --end 60 --output result_udp.jsonStart a local HTTP server in one terminal:
python -m http.server 8000Run scanner in another terminal:
python port_scanner.py 127.0.0.1 --scan-type tcp --start 7990 --end 8010 --bannerExpected result: port 8000 should appear as open.
The scanner writes a JSON report with fields like:
target,target_ipscan_typeport_rangethreads,timeout,banner_modestarted_at,duration_secondstotal_scanned,total_interestingdetected_ports(list ofport,protocol,state,service,banner)
Run all tests:
python -m unittest discover -s tests -v- UDP scanning is less reliable than TCP by nature;
open|filteredis common. - Banner grabbing works only for TCP mode.
- Firewalls can hide real port states.
- Built basic TCP scanner
- Added input validation
- Added timing, summary stats, and JSON export
- Added optional banner detection
- Added UDP scan mode
- Refactored into modules
- Added tests
- Added project documentation