📜  现在,我们将首先看一下使用 Python 扫描端口的最简单方法——无论(1)

📅  最后修改于: 2023-12-03 14:56:14.650000             🧑  作者: Mango

扫描端口的最简单方法

现在,我们将介绍如何使用 Python 扫描端口的最简单方法。通过这种方法,你可以快速地扫描一个指定 IP 的所有开放端口,或者指定一个端口范围进行扫描。

大纲
  1. 导入必要的模块
  2. 获取用户输入
  3. 扫描单个端口
  4. 扫描端口范围
  5. 异常处理
  6. 结论
导入必要的模块
import socket
import argparse

我们需要导入 socket 模块,以便能够进行网络连接和数据通信。也需要导入 argparse 模块,以方便处理用户输入参数。

获取用户输入
parser = argparse.ArgumentParser(description='Scan ports for an IP address.')
parser.add_argument('-p', '--ports', nargs='+', dest='ports', default=[80], type=int, help='Port(s) to scan (default 80)')
parser.add_argument('host', type=str, help='Host to scan')
hostname = parser.parse_args().host
ports = parser.parse_args().ports

在此我们使用 argparse 模块来解析程序的命令行参数。程序需要用户提供要扫描的主机名或 IP 地址,并可以选择扫描的端口范围。如果没有指定端口,则默认扫描 80 端口。

扫描单个端口
def scan_port(host, port):
    try:
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.settimeout(2)
            s.connect((host, port))
            s.shutdown(socket.SHUT_RDWR)
            return True
    except:
        return False

for port in ports:
    result = scan_port(hostname, port)
    if result:
        print(f'Port {port} is open')
    else:
        print(f'Port {port} is closed')

我们定义了一个名为 scan_port 的函数,它将尝试连接指定主机的指定端口。如果连接成功,则认为该端口为开放状态,否则该端口为关闭状态。

在主程序中,我们简单地遍历要扫描的端口列表,并对每个端口运行 scan_port 函数。如果返回 True,则打印该端口为开放状态。否则打印该端口为关闭状态。

扫描端口范围
def scan_ports_range(host, start_port, end_port):
    open_ports = []
    for port in range(start_port, end_port+1):
        if scan_port(host, port):
            open_ports.append(port)
    return open_ports

if len(ports) == 1:
    result = scan_port(hostname, ports[0])
    if result:
        print(f'Port {ports[0]} is open')
    else:
        print(f'Port {ports[0]} is closed')
else:
    open_ports = scan_ports_range(hostname, ports[0], ports[-1])
    for port in open_ports:
        print(f'Port {port} is open')

如果用户指定了一个端口范围,则使用 scan_ports_range 函数扫描该范围内的所有端口。该函数将返回开放状态的端口列表。

如果只有一个端口要扫描,则直接调用 scan_port 函数扫描该端口。

异常处理
def scan_port(host, port):
    try:
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.settimeout(2)
            s.connect((host, port))
            s.shutdown(socket.SHUT_RDWR)
            return True
    except (socket.timeout, ConnectionRefusedError):
        return False
    except:
        print(f'Unknown error scanning port {port}')
        return False

我们可以使用多个 except 语句来捕获可能发生的非预期错误(如超时、连接被拒绝等等)。这样可以增强程序的健壮性。

结论

至此,我们已经介绍了使用 Python 进行端口扫描的最简单方法。这种方法是一个起点,你可以根据实际需求进行修改和扩展。如果你想进一步了解这方面的知识,请继续阅读相关文献。