Threaded Port Scanner
Build a port scanner in C++ that checks which network ports are open on a host you specify, like a tiny version of nmap. It tries many ports at once, but never more than a set limit, with a timeout for each, and reports each port as open, closed (refused) or filtered (no answer), with the common service name (such as 22 for ssh). It's built on Boost.Asio for asynchronous connections. Only scan machines you own or have explicit permission to test; scanning other people's systems can be illegal. The tool only accepts targets you type in explicitly and refuses ranges of addresses. You'll learn TCP connections and what their outcomes mean, asynchronous networking with Boost.Asio, limiting concurrency, timeouts, and building responsible security tools.
- Estimate
- ~10.5h
- Steps
- 6
- Completed by
- 0
- Proposed by
- codeseed.app
CMake · Boost.Asio
Project roadmap
- 01
Define the tool and its limits
~1.5hWrite README.md: the usage (scanner HOST --ports 1-1024 or --ports 22,80,443, --concurrency, --timeout, --output json), the three possible results per port and what each means, and the safety rules: one host per run, a maximum number of ports, no address ranges, and a warning printed at start that you must be allowed to scan the target. Set up a CMake project with Boost. Done when: README.md defines the usage, results and rules.
- 02
Parse the input
~1.5hParse the host (resolve it with Boost.Asio's resolver, and report when it can't be resolved), the port list (single ports, ranges and comma lists, from 1 to 65535, removing duplicates) and the options, with clear errors for invalid values. Write unit tests for the port list parser. Done when: the parser tests pass, and invalid input prints clear errors.
- 03
Check one port
~2hWith Boost.Asio, start an async_connect to the host and port along with a steady_timer for the timeout. If the connection succeeds, the port is open; if it's refused, closed; if the timer fires first, cancel the socket and mark it filtered. Close the socket right after. Done when: checking ports on your own machine correctly finds an open port (for example a local web server) and a closed one.
- 04
Scan many ports with a limit
~2hScan the port list with at most --concurrency checks in progress at once: start that many, and start the next one whenever one finishes, all on one io_context (optionally run on a few threads with a strand protecting the shared results). Show progress for big scans. Done when: scanning 1,000 ports of your own machine finishes quickly with at most the chosen number of connections open at once.
- 05
Report the results
~1.5hPrint open ports sorted by number with a service name from a small built-in table (22 ssh, 80 http, 443 https and so on), a count of closed and filtered ports, and the time taken. Add --output json. Exit with code 0 when the scan completes, and a different code for input or resolution errors. Done when: the report lists the open ports on your test machine correctly.
- 06
Test it
~2hWrite tests that open listening sockets on local ports inside the test, then scan localhost: open ports found, closed ports reported, a filtered case simulated with a very short timeout against a non-routable test address, and the concurrency limit respected. Add a Docker Compose setup with a few services to scan as a safe practice target. Done when: the tests pass, and scanning the practice setup gives the expected results.
Ready to build this?
Get a GitHub repo and start building. Your AI reviewer checks each step as you go.
Tech stack