Python基于多线程实现ping扫描功能示例的攻略如下:
1. 确定需求,安装需要的模块
首先需要明确的是,我们要实现的是ping扫描功能,而用Python实现ping扫描功能的话,我们还需要一个能够发送ICMP请求的模块,常用的有ping3
、pythonping
等。
这里以ping3
模块为例,我们可以通过以下命令进行安装:
pip install ping3
2. 实现ping扫描功能
之后就可以开始实现ping扫描功能了。我们利用多线程并发的方式实现这一功能,通过开启多个线程并行地发送ICMP请求,大大提高了扫描速度。扫描步骤如下:
- 输入需要扫描的IP地址段
- 构造IP地址列表
- 并发地发送ICMP请求,一旦有回应即表示该IP地址可用
以下是示例代码1,可以实现从192.168.0.1到192.168.0.255的IP地址段的ping扫描:
import threading
import queue
import ping3
# 构造IP地址列表
ip_list = ['192.168.0.%d' % i for i in range(1, 256)]
# 设置并发数量及线程队列
concurrent_num = 50
queue_lock = threading.Lock()
work_queue = queue.Queue(len(ip_list))
for ip in ip_list:
work_queue.put(ip)
# 实现ping的功能
def do_ping(ip):
response = ping3.ping(ip, timeout=1)
if response is not None:
print(f'{ip}: Ping OK')
# 实现线程的功能
def worker():
while not work_queue.empty():
queue_lock.acquire()
ip = work_queue.get()
queue_lock.release()
do_ping(ip)
# 开启多线程
threads = []
for i in range(concurrent_num):
t = threading.Thread(target=worker)
threads.append(t)
t.start()
# 等待所有线程结束
for t in threads:
t.join()
print('All done!')
3.优化扫描速度
由于ping扫描功能相对耗时,我们可以通过以下两种方法来优化扫描速度:
- 缩减扫描范围,只扫描开启了指定端口的主机
这种方法可以通过构造TCP连接实现,下面是示例代码2,实现只对开启了80端口的主机进行扫描:
import threading
import queue
import socket
# 构造IP地址列表
ip_list = ['192.168.0.%d' % i for i in range(1, 256)]
# 设置并发数量及线程队列
concurrent_num = 50
queue_lock = threading.Lock()
work_queue = queue.Queue(len(ip_list))
for ip in ip_list:
work_queue.put(ip)
PORT = 80
# 实现检查指定ip的tcp端口是否开放的功能
def do_tcp_scan(ip):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.settimeout(1)
if s.connect_ex((ip, PORT)) == 0:
print(f'{ip}: Port {PORT} is open.')
# 实现线程的功能
def worker():
while not work_queue.empty():
queue_lock.acquire()
ip = work_queue.get()
queue_lock.release()
do_tcp_scan(ip)
# 开启多线程
threads = []
for i in range(concurrent_num):
t = threading.Thread(target=worker)
threads.append(t)
t.start()
# 等待所有线程结束
for t in threads:
t.join()
print('All done!')
- 利用协程优化并发发送ICMP请求
通过协程并发执行ping请求也可以提高扫描速度。以下是示例代码3:
import threading
import queue
import ping3
import asyncio
# 构造IP地址列表
ip_list = ['192.168.0.%d' % i for i in range(1, 256)]
# 设置并发数量及线程队列
concurrent_num = 50
queue_lock = threading.Lock()
work_queue = queue.Queue(len(ip_list))
for ip in ip_list:
work_queue.put(ip)
# 实现ping的功能
async def do_ping(ip):
response = await loop.run_in_executor(None, ping3.ping, ip)
if response is not None:
print(f'{ip}: Ping OK')
# 实现协程的功能
async def worker():
while not work_queue.empty():
queue_lock.acquire()
ip = work_queue.get()
queue_lock.release()
await do_ping(ip)
async def main():
tasks = [worker() for _ in range(concurrent_num)]
await asyncio.gather(*tasks)
# 开启多线程
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(main())
finally:
loop.run_until_complete(loop.shutdown_asyncgens())
loop.close()
print('All done!')
总结:
本文讲解了Python基于多线程实现ping扫描功能的攻略,介绍了两种优化扫描速度的方法。其中,示例代码1实现了从192.168.0.1到192.168.0.255的IP地址段的ping扫描,示例代码2实现了只对开启了80端口的主机进行扫描,示例代码3使用了协程并发执行ping请求。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python基于多线程实现ping扫描功能示例 - Python技术站