Practical Example: Scanning IP and Port Combinations
๐ท๏ธ Loops and Iteration / Nested Loops
๐ง Context Introduction
When working with networked systems, one of the most common tasks is checking whether specific services are running on particular machines. This often involves testing combinations of IP addresses and port numbers. A nested loop is the perfect tool for this job โ it allows you to systematically iterate through every IP in a list and, for each IP, check every port in a separate list. This practical example will walk you through building a simple IP and port scanner using nested loops.
๐ต๏ธ What We Are Building
We are creating a script that: - Takes a list of IP addresses - Takes a list of port numbers - Uses a nested loop to test each IP against each port - Simulates a connection attempt (or prints a status message) for each combination
This is a foundational pattern used in network diagnostics, security audits, and service discovery.
โ๏ธ The Core Concept: Nested Loops for Combinations
A nested loop means one loop runs inside another. For every iteration of the outer loop, the inner loop runs completely through all its iterations.
How it applies here: - Outer loop: Iterates over each IP address - Inner loop: Iterates over each port number for the current IP
This creates a full cross-product of all IP and port combinations.
๐ ๏ธ Step-by-Step Script Breakdown
Step 1: Define your data - Create a list called ip_list containing IP addresses as strings (for example: "192.168.1.1", "192.168.1.2", "10.0.0.1") - Create a list called port_list containing port numbers as integers (for example: 22, 80, 443, 8080)
Step 2: Write the outer loop - Use a for loop to iterate over each IP in ip_list - Inside this loop, print a header message like "Scanning IP: {current_ip}" to show which IP is being checked
Step 3: Write the inner loop - Inside the outer loop, write another for loop to iterate over each port in port_list - For each port, print a message like "Checking port {port} on {ip}"
Step 4: Add a simulated check - To make it realistic, you can use a conditional statement to simulate whether a port is open or closed - For demonstration, you might mark port 22 and 80 as "open" and everything else as "closed" - Print the result for each combination
๐ Comparison: Without Nested Loops vs With Nested Loops
| Aspect | Without Nested Loops | With Nested Loops |
|---|---|---|
| Code structure | Requires separate loops for each IP or manual repetition | One clean, compact structure |
| Scalability | Hard to add more IPs or ports without rewriting code | Easily extend lists and the loop handles everything |
| Readability | Messy and error-prone | Clear and logical |
| Maintenance | High effort for changes | Low effort โ just update the lists |
๐งช Example Output (Conceptual)
When you run the script, the output would look something like this (formatted as inline text):
Scanning IP: 192.168.1.1
Checking port 22 on 192.168.1.1 โ Status: Open
Checking port 80 on 192.168.1.1 โ Status: Open
Checking port 443 on 192.168.1.1 โ Status: Closed
Checking port 8080 on 192.168.1.1 โ Status: Closed
Scanning IP: 192.168.1.2
Checking port 22 on 192.168.1.2 โ Status: Open
Checking port 80 on 192.168.1.2 โ Status: Closed
Checking port 443 on 192.168.1.2 โ Status: Open
Checking port 8080 on 192.168.1.2 โ Status: Closed
๐ Real-World Extensions
Once you understand the nested loop pattern, you can extend this script in many useful ways:
- Add timeout handling to avoid hanging on unresponsive IPs
- Use socket connections to actually attempt connecting to ports instead of simulating
- Log results to a file for later analysis
- Add threading to scan multiple IPs simultaneously for faster results
- Filter by port to only scan specific services like web servers (port 80, 443) or SSH (port 22)
โ Key Takeaways
- Nested loops are ideal for working with combinations of two or more lists
- The outer loop controls the first dimension (IPs), and the inner loop controls the second dimension (ports)
- This pattern is widely used in network scanning, configuration validation, and data processing
- Start simple with print statements, then gradually add real functionality like socket connections
- Always test with small lists first to verify your logic before scaling up
By mastering this nested loop pattern, you gain a powerful tool for automating repetitive checks across multiple systems and services.
This example shows how to use nested loops to systematically test combinations of IP addresses and port numbers, simulating a basic network scan.
๐ Example 1: Scanning a single IP with multiple ports
Demonstrates the simplest nested loop: one IP address tested against a list of common ports.
ip_address = "192.168.1.1"
ports = [22, 80, 443]
for port in ports:
print(f"Scanning {ip_address}:{port}")
๐ค Output: Scanning 192.168.1.1:22
Scanning 192.168.1.1:80
Scanning 192.168.1.1:443
๐ Example 2: Scanning multiple IPs with a single port
Shows how to iterate over a list of IP addresses while keeping the port fixed.
ip_addresses = ["192.168.1.1", "192.168.1.2", "192.168.1.3"]
port = 80
for ip in ip_addresses:
print(f"Scanning {ip}:{port}")
๐ค Output: Scanning 192.168.1.1:80
Scanning 192.168.1.2:80
Scanning 192.168.1.3:80
๐ Example 3: Full IP and port combination scan
Uses nested loops to test every IP against every port in separate lists.
ip_addresses = ["192.168.1.1", "192.168.1.2"]
ports = [22, 80, 443]
for ip in ip_addresses:
for port in ports:
print(f"Scanning {ip}:{port}")
๐ค Output: Scanning 192.168.1.1:22
Scanning 192.168.1.1:80
Scanning 192.168.1.1:443
Scanning 192.168.1.2:22
Scanning 192.168.1.2:80
Scanning 192.168.1.2:443
๐ Example 4: Generating IP range with port scan
Generates a small range of IP addresses dynamically and scans each with multiple ports.
base_ip = "192.168.1"
ports = [22, 80]
for last_octet in range(1, 4):
ip = f"{base_ip}.{last_octet}"
for port in ports:
print(f"Scanning {ip}:{port}")
๐ค Output: Scanning 192.168.1.1:22
Scanning 192.168.1.1:80
Scanning 192.168.1.2:22
Scanning 192.168.1.2:80
Scanning 192.168.1.3:22
Scanning 192.168.1.3:80
๐ Example 5: Practical scan with status reporting
Simulates a realistic scan by checking if a port is "open" or "closed" using a condition inside the nested loop.
ip_addresses = ["10.0.0.1", "10.0.0.2"]
ports = [22, 443]
open_ports = {"10.0.0.1": [22], "10.0.0.2": [443]}
for ip in ip_addresses:
for port in ports:
if port in open_ports.get(ip, []):
status = "OPEN"
else:
status = "CLOSED"
print(f"{ip}:{port} - {status}")
๐ค Output: 10.0.0.1:22 - OPEN
10.0.0.1:443 - CLOSED
10.0.0.2:22 - CLOSED
10.0.0.2:443 - OPEN
Comparison Table
| Example | IPs Scanned | Ports Scanned | Dynamic IP Generation | Status Reporting |
|---|---|---|---|---|
| 1 | 1 | 3 | No | No |
| 2 | 3 | 1 | No | No |
| 3 | 2 | 3 | No | No |
| 4 | 3 | 2 | Yes | No |
| 5 | 2 | 2 | No | Yes |
๐ง Context Introduction
When working with networked systems, one of the most common tasks is checking whether specific services are running on particular machines. This often involves testing combinations of IP addresses and port numbers. A nested loop is the perfect tool for this job โ it allows you to systematically iterate through every IP in a list and, for each IP, check every port in a separate list. This practical example will walk you through building a simple IP and port scanner using nested loops.
๐ต๏ธ What We Are Building
We are creating a script that: - Takes a list of IP addresses - Takes a list of port numbers - Uses a nested loop to test each IP against each port - Simulates a connection attempt (or prints a status message) for each combination
This is a foundational pattern used in network diagnostics, security audits, and service discovery.
โ๏ธ The Core Concept: Nested Loops for Combinations
A nested loop means one loop runs inside another. For every iteration of the outer loop, the inner loop runs completely through all its iterations.
How it applies here: - Outer loop: Iterates over each IP address - Inner loop: Iterates over each port number for the current IP
This creates a full cross-product of all IP and port combinations.
๐ ๏ธ Step-by-Step Script Breakdown
Step 1: Define your data - Create a list called ip_list containing IP addresses as strings (for example: "192.168.1.1", "192.168.1.2", "10.0.0.1") - Create a list called port_list containing port numbers as integers (for example: 22, 80, 443, 8080)
Step 2: Write the outer loop - Use a for loop to iterate over each IP in ip_list - Inside this loop, print a header message like "Scanning IP: {current_ip}" to show which IP is being checked
Step 3: Write the inner loop - Inside the outer loop, write another for loop to iterate over each port in port_list - For each port, print a message like "Checking port {port} on {ip}"
Step 4: Add a simulated check - To make it realistic, you can use a conditional statement to simulate whether a port is open or closed - For demonstration, you might mark port 22 and 80 as "open" and everything else as "closed" - Print the result for each combination
๐ Comparison: Without Nested Loops vs With Nested Loops
| Aspect | Without Nested Loops | With Nested Loops |
|---|---|---|
| Code structure | Requires separate loops for each IP or manual repetition | One clean, compact structure |
| Scalability | Hard to add more IPs or ports without rewriting code | Easily extend lists and the loop handles everything |
| Readability | Messy and error-prone | Clear and logical |
| Maintenance | High effort for changes | Low effort โ just update the lists |
๐งช Example Output (Conceptual)
When you run the script, the output would look something like this (formatted as inline text):
Scanning IP: 192.168.1.1
Checking port 22 on 192.168.1.1 โ Status: Open
Checking port 80 on 192.168.1.1 โ Status: Open
Checking port 443 on 192.168.1.1 โ Status: Closed
Checking port 8080 on 192.168.1.1 โ Status: Closed
Scanning IP: 192.168.1.2
Checking port 22 on 192.168.1.2 โ Status: Open
Checking port 80 on 192.168.1.2 โ Status: Closed
Checking port 443 on 192.168.1.2 โ Status: Open
Checking port 8080 on 192.168.1.2 โ Status: Closed
๐ Real-World Extensions
Once you understand the nested loop pattern, you can extend this script in many useful ways:
- Add timeout handling to avoid hanging on unresponsive IPs
- Use socket connections to actually attempt connecting to ports instead of simulating
- Log results to a file for later analysis
- Add threading to scan multiple IPs simultaneously for faster results
- Filter by port to only scan specific services like web servers (port 80, 443) or SSH (port 22)
โ Key Takeaways
- Nested loops are ideal for working with combinations of two or more lists
- The outer loop controls the first dimension (IPs), and the inner loop controls the second dimension (ports)
- This pattern is widely used in network scanning, configuration validation, and data processing
- Start simple with print statements, then gradually add real functionality like socket connections
- Always test with small lists first to verify your logic before scaling up
By mastering this nested loop pattern, you gain a powerful tool for automating repetitive checks across multiple systems and services.
Interactive Views
You are currently in ๐ All-in-One mode. Use the tabs at the top to switch to ๐ Theory Only or ๐ป Code Only views.
This example shows how to use nested loops to systematically test combinations of IP addresses and port numbers, simulating a basic network scan.
๐ Example 1: Scanning a single IP with multiple ports
Demonstrates the simplest nested loop: one IP address tested against a list of common ports.
ip_address = "192.168.1.1"
ports = [22, 80, 443]
for port in ports:
print(f"Scanning {ip_address}:{port}")
๐ค Output: Scanning 192.168.1.1:22
Scanning 192.168.1.1:80
Scanning 192.168.1.1:443
๐ Example 2: Scanning multiple IPs with a single port
Shows how to iterate over a list of IP addresses while keeping the port fixed.
ip_addresses = ["192.168.1.1", "192.168.1.2", "192.168.1.3"]
port = 80
for ip in ip_addresses:
print(f"Scanning {ip}:{port}")
๐ค Output: Scanning 192.168.1.1:80
Scanning 192.168.1.2:80
Scanning 192.168.1.3:80
๐ Example 3: Full IP and port combination scan
Uses nested loops to test every IP against every port in separate lists.
ip_addresses = ["192.168.1.1", "192.168.1.2"]
ports = [22, 80, 443]
for ip in ip_addresses:
for port in ports:
print(f"Scanning {ip}:{port}")
๐ค Output: Scanning 192.168.1.1:22
Scanning 192.168.1.1:80
Scanning 192.168.1.1:443
Scanning 192.168.1.2:22
Scanning 192.168.1.2:80
Scanning 192.168.1.2:443
๐ Example 4: Generating IP range with port scan
Generates a small range of IP addresses dynamically and scans each with multiple ports.
base_ip = "192.168.1"
ports = [22, 80]
for last_octet in range(1, 4):
ip = f"{base_ip}.{last_octet}"
for port in ports:
print(f"Scanning {ip}:{port}")
๐ค Output: Scanning 192.168.1.1:22
Scanning 192.168.1.1:80
Scanning 192.168.1.2:22
Scanning 192.168.1.2:80
Scanning 192.168.1.3:22
Scanning 192.168.1.3:80
๐ Example 5: Practical scan with status reporting
Simulates a realistic scan by checking if a port is "open" or "closed" using a condition inside the nested loop.
ip_addresses = ["10.0.0.1", "10.0.0.2"]
ports = [22, 443]
open_ports = {"10.0.0.1": [22], "10.0.0.2": [443]}
for ip in ip_addresses:
for port in ports:
if port in open_ports.get(ip, []):
status = "OPEN"
else:
status = "CLOSED"
print(f"{ip}:{port} - {status}")
๐ค Output: 10.0.0.1:22 - OPEN
10.0.0.1:443 - CLOSED
10.0.0.2:22 - CLOSED
10.0.0.2:443 - OPEN
Comparison Table
| Example | IPs Scanned | Ports Scanned | Dynamic IP Generation | Status Reporting |
|---|---|---|---|---|
| 1 | 1 | 3 | No | No |
| 2 | 3 | 1 | No | No |
| 3 | 2 | 3 | No | No |
| 4 | 3 | 2 | Yes | No |
| 5 | 2 | 2 | No | Yes |