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