3.1 问题
创建mtping.py脚本,实现以下功能:
通过ping测试主机是否可达
如果ping不通,不管什么原因都认为主机不可用
通过多线程方式实现并发扫描
3.2 方案
subprocess.call ()方法可以调用系统命令,其返回值是系统命令退出码,也就是如果系统命令成功执行,返回0,如果没有成功执行,返回非零值。
调用Ping对象,可以调用系统的ping命令,通过退出码来判断是否ping通了该主机。如果顺序执行,每个ping操作需要消耗数秒钟,全部的254个地址需要10分钟以上。而采用多线程,可以实现对这254个地址同时执行ping操作,并发的结果就是将执行时间缩短到了10秒钟左右。
3.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:编写脚本
[root@localhost day09]# vim mtping.py
#!/usr/bin/env python3
import subprocess
import threading
def ping(host):
rc = subprocess.call(
'ping -c2 %s &> /dev/null' % host,
shell=True
)
if rc:
print('%s: down' % host)
else:
print('%s: up' % host)
if __name__ == '__main__':
ips = ['172.40.58.%s' % i for i in range(1, 255)]
for ip in ips:
# 创建线程,ping是上面定义的函数, args是传给ping函数的参数
t = threading.Thread(target=ping, args=(ip,))
t.start() # 执行ping(ip)
面向对象代码编写方式如下:
定义Ping类,该类可实现允许ping通任何主机功能:
1.利用__init__方法初始化参数,当调用Ping类实例时,该方法自动调用
- 利用__call__()方法让Ping类实例变成一个可调用对象调用,调用t.start()时, 引用subprocess模块执行shell命令ping所有主机,将执行结果返回给rc变量,此时,如果ping不通返回结果为1,如果能ping通返回结果为0
3.如果rc变量值不为0,表示ping不通,输出down
4.否则,表示可以ping通,输出up
利用列表推导式生成整个网段的IP地址列表[172.40.58.1,172.40.58.2…]
循环遍历整个网段列表,直接利用 Thread 类来创建线程对象,执行Ping(ip)。
[root@localhost day09]# vim mtping2.py
#!/usr/bin/env python3
import threading
import subprocess
class Ping:
def __init__(self, host):
self.host = host
def __call__(self):
rc = subprocess.call(
'ping -c2 %s &> /dev/null' % self.host,
shell=True
)
if rc:
print('%s: down' % self.host)
else:
print('%s: up' % self.host)
if __name__ == '__main__':
ips = ('172.40.58.%s' % i for i in range(1, 255)) # 创建生成器
for ip in ips:
# 创建线程,Ping是上面定义的函数
t = threading.Thread(target=Ping(ip)) # 创建Ping的实例
t.start() #执行Ping(ip)
步骤二:测试脚本执行
[root@localhost day09]# python3 udp_time_serv.py
172.40.58.1: up
172.40.58.69: up
172.40.58.87: up
172.40.58.90: up
172.40.58.102: up
172.40.58.101: up
172.40.58.105: up
172.40.58.106: up
172.40.58.108: up
172.40.58.110: up
172.40.58.109: up
...
...
...
...
172.40.58.241: down
172.40.58.242: down
172.40.58.243: down
172.40.58.245: down
172.40.58.246: down
172.40.58.248: down
172.40.58.247: down
172.40.58.250: down
172.40.58.249: down
172.40.58.251: down
172.40.58.252: down
172.40.58.253: down
172.40.58.254: down