上一篇文章我们实现了 ping 检测单个或少量主机。但如果要扫描整个局域网(比如 192.168.1.1-254),就需要更高效的方法。
本篇用多线程 + ping 实现局域网批量扫描。
原理说明
局域网扫描的核心思路:
- 生成目标 IP 列表(通常是同一网段的所有 IP)
- 用多线程并发 ping 每个 IP
- 收集返回结果
注意:扫描局域网需要授权,只扫描自己的设备范围。
安装依赖
本篇只需要 Python 内置库,无需额外安装。
基础版:生成 IP 列表
import ipaddress
def generate_ip_range(network, start_last_octet=1, end_last_octet=254):
net = ipaddress.ip_network(f"{network}/24", strict=False)
ips = []
for ip in net.hosts():
if start_last_octet <= ip.packed[3] <= end_last_octet:
ips.append(str(ip))
return ips
if __name__ == '__main__':
ips = generate_ip_range('192.168.1.0')
print(f"共生成 {len(ips)} 个 IP 地址")
print(f"前10个: {ips[:10]}")
print(f"后10个: {ips[-10:]}")测试运行:
共生成 254 个 IP 地址
前10个: ['192.168.1.1', '192.168.1.2', ...]
后10个: ['192.168.1.245', ...]
成功生成 254 个 IP 地址。
进阶版:多线程扫描局域网
import subprocess, platform, time
from concurrent.futures import ThreadPoolExecutor, as_completed
def ping_ip(host, timeout=1):
try:
cmd = ['ping', '-n', '1', '-w', str(timeout*1000), host] if platform.system() == 'Windows' else ['ping', '-c', '1', '-W', str(timeout), host]
result = subprocess.run(cmd, capture_output=True, timeout=timeout+1)
return {'ip': host, 'online': result.returncode == 0}
except:
return {'ip': host, 'online': False}
def scan_network(network, max_workers=50, timeout=1):
ips = generate_ip_range(network)
online_hosts = []
with ThreadPoolExecutor(max_workers=max_workers) as executor:
future_to_ip = {executor.submit(ping_ip, ip, timeout): ip for ip in ips}
for future in as_completed(future_to_ip):
result = future.result()
if result['online']:
online_hosts.append(result['ip'])
return online_hosts测试运行:
耗时: 8.54 秒
在线主机: 2 个
扫描成功!254 个 IP 仅耗时 8.54 秒。
优化版:只扫描常见段
def quick_scan_network(network):
net = ipaddress.ip_network(f"{network}/24", strict=False)
return [str(ip) for ip in net.hosts() if ip.packed[3] not in range(11,99) and ip.packed[3] not in range(111,253)]整合版:带端口检测
import socket
from concurrent.futures import ThreadPoolExecutor
def check_port(ip, port, timeout=1):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(timeout)
result = sock.connect_ex((ip, port))
sock.close()
return result == 0
except:
return False实际应用场景
- 找出局域网内所有在线设备 — 资产管理
- 发现新接入的设备 — 发现未知设备报警
- 快速定位网关 — 确认哪个 IP 是路由器
- 网络故障排查 — 快速确认哪些设备可达
注意事项
- 扫描速度:30-50 并发线程比较安全
- 超时时间:内网扫描用 1 秒超时足够
- 授权:只扫描自己授权的网络范围
- 法律风险:扫描他人网络可能违法
测试环境说明
- Python 版本: 3.14.3
- 操作系统: Windows 10