#!/usr/bin/env python
# -*- coding: utf-8 -*-
import subprocess
import ipaddress
import time
def ping_ip(ip, timeout=1, retries=5, delay=1):
"""Ping an IP address multiple times with a timeout."""
success = False
for _ in range(retries):
try:
# 使用subprocess执行Windows的ping命令,并设置超时
# 注意:Windows使用-n,Linux使用-c
param = ['ping', '-n', '1', '-w', str(timeout * 1000), ip] # 注意:-w 的单位是毫秒
result = subprocess.run(param, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True,
timeout=(timeout + 2))
# 检查ping是否成功
# 通常,如果ping成功,result.stdout会包含"TTL="等字样
# 但更可靠的方式是检查returncode是否为0(可能需要根据你的环境调整)
if "TTL=" in result.stdout: # 或者 if result.returncode == 0:
success = True
break
else:
print(f"Ping failed for {ip}: {result.stderr}")
time.sleep(delay) # 等待一段时间后重试
except subprocess.TimeoutExpired:
print(f"Ping timed out for {ip}")
time.sleep(delay)
except subprocess.CalledProcessError as e:
# 当returncode不为0时,subprocess.run会抛出CalledProcessError
# 但由于我们已经检查了stdout,这里可能不需要额外的处理
print(f"Ping failed with error code {e.returncode} for {ip}")
break # 如果ping失败,可以选择不再重试
def find_unused_ips(network, prefix_len=24, ping_count=5):
"""Find unused IPs in a given network."""
net = ipaddress.ip_network(f"{network}/{prefix_len}", strict=False)
unused_ips = []
# 跳过.1(通常是网关)和.255(广播地址)
for host in net.hosts():
if host.is_private and not (host.exploded[-1] == '1' or host.exploded[-1] == '255'):
if not ping_ip(str(host), ping_count):
unused_ips.append(str(host))
return unused_ips
# 假设我们要扫描的网段是192.168.21.x
network = '192.168.21.0'
unused_ips = find_unused_ips(network)
print("Unused IPs in the network:", unused_ips)