June 25, 2026
Building a TCP Port Scanner from Scratch
Introduction
By Sumit0xf
1 min read
Introduction
- The Hook: When entering cybersecurity, everyone learns how to run
nmap -sV. But running a tool blindly doesn't make you a great security researcher. To truly understand network protocols, you have to build the tools yourself. - The Project: In this write-up, I break down how I built a functional, multi-threaded TCP port scanner from scratch, the mechanics of the TCP handshake, and what I learned during the build.
🧠 The Core Concept: The TCP 3-Way Handshake
To scan a port, your code has to interact with the target machine's operating system using the standard TCP protocol.
- Open Port: Your scanner sends a
SYN(Synchronize) packet. If the port is open, the target replies with aSYN-ACK(Synchronize-Acknowledgment). Your scanner completes the link with anACKor immediately drops it (RST) once verified. - Closed Port: The target responds with a
RST(Reset) packet immediately, telling your script to move on.
import socket
target = “192.168.0.112”
ports = [21, 22, 23, 80, 443, 3306, 8080]
print(f”Scanning {target}…”)
for port in ports:
# 1. Initialize an IPv4 (AF_INET) TCP (SOCK_STREAM) socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. Set a 1-second timeout so the script doesn’t hang on filtered ports
sock.settimeout(1)
# 3. Attempt connection; returns 0 if connection succeeds
result = sock.connect_ex((target, port))
if result == 0:
print(f”[OPEN] Port {port}”)
else:
print(f”[CLOSED/FILTERED] Port {port}”)
# 4. Explicitly close the socket descriptor to free up system resources
sock.close()import socket
target = “192.168.0.112”
ports = [21, 22, 23, 80, 443, 3306, 8080]
print(f”Scanning {target}…”)
for port in ports:
# 1. Initialize an IPv4 (AF_INET) TCP (SOCK_STREAM) socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. Set a 1-second timeout so the script doesn’t hang on filtered ports
sock.settimeout(1)
# 3. Attempt connection; returns 0 if connection succeeds
result = sock.connect_ex((target, port))
if result == 0:
print(f”[OPEN] Port {port}”)
else:
print(f”[CLOSED/FILTERED] Port {port}”)
# 4. Explicitly close the socket descriptor to free up system resources
sock.close()🛠️ Breaking Down the Key Functions:
socket.AF_INET&socket.SOCK_STREAM: This tells our operating system that we want to communicate over standard IPv4 and establish a full, three-way TCP handshake connection.sock.connect_ex(): This is the secret weapon of the script. Instead of throwing an error when a port is closed (which would crash the loop), it gracefully returns an error code. In UNIX networking standards, an error code of0means complete success—the handshake was accepted, meaning the port is listening.sock.settimeout(1): Crucial for speed. If a port is behind a stealth firewall, the packet is simply dropped. Without a timeout, your script might hang for up to 20 seconds waiting for an answer on every single closed port.
Below you can also check my github repository for other builds also.
cybersecurity-journey/scripts.md at main · sumit0xf/cybersecurity-journey Breaking things to understand how to secure them. Focused on AI security research. - cybersecurity-journey/scripts.md…