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